C#一个普通的类,怎么获取窗体里控件的属性?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#一个普通的类,怎么获取窗体里控件的属性?相关的知识,希望对你有一定的参考价值。

把窗体本身或者控件传入这个类(或者做为参数传给这个类的方法),看你的需要了,比如说你在form1里创建的这个类叫myclass,把这个mycalss的构造方法改成
public class myclass

form1 frm;
public myclass(form1 frm)

this.frm=frm;


这样你在form1中创建这个myclass的时候就可以是
myclass mc=new myclass(this);
当然也可以直接传窗体或者控件给类中的方法,比如mycalss中有
public void msg(EditText txt)
或者
public void msg(form1 frm)
其它方法也很多,看你需要了。
参考技术A 如果是为第二个窗体添加带参构造。窗体也是类,也可以重载构造函数的。但添加的工作也只能在第二个窗体去做,第一个窗体负责获取数据数组,传进去就好了。在一个窗体里调用另一个窗体的控件,本身就是不好的行为
如果frmmain已经先处于运行状态,lz应该去获取frmmain的当前活动窗体frmmain
f
=
frmmain.activeform;(activeform是静态属性),而不是去创建一个窗体.

C# 获取窗体上控件的位置

【中文标题】C# 获取窗体上控件的位置【英文标题】:C# Get a control's position on a form 【发布时间】:2010-12-01 11:18:40 【问题描述】:

当控件可能位于其他控件(如面板)内时,是否有任何方法可以检索表单中控件的位置?

控件的 Left 和 Top 属性只提供了它在其父控件中的位置,但如果我的控件位于五个嵌套面板中,并且我需要它在窗体上的位置怎么办?

快速示例:

按钮 btnA 位于面板 pnlB 内的坐标 (10,10) 上。 面板 pnlB 位于窗体 frmC 内的坐标 (15,15) 上。

我想要 btnA 在 frmC 上的位置,即 (25,25)。

我可以得到这个位置吗?

【问题讨论】:

【参考方案1】:

您可以遍历父母,注意他们在父母中的位置,直到您到达表格。

编辑:类似(未经测试):

public Point GetPositionInForm(Control ctrl)

   Point p = ctrl.Location;
   Control parent = ctrl.Parent;
   while (! (parent is Form))
   
      p.Offset(parent.Location.X, parent.Location.Y);
      parent = parent.Parent;
   
   return p;

【讨论】:

是的,我想到了,但这似乎是一种不切实际的方法,所以我希望有另一种方法。如果没有人有任何其他建议,这就是我会做的。 这就是这样做的方法,用一个简单的递归函数。【参考方案2】:

您可以使用控件PointToScreen 方法获取相对于屏幕的绝对位置。

您可以使用 Forms PointToScreen 方法,并通过基本数学运算,获取控件的位置。

【讨论】:

这不会完全正确,除非您考虑到标题栏的高度和表单边框的宽度。 这对获取控件的绝对位置有何帮助?您必须将 Point 对象传递给 PointToScreen(),这在这种情况下没有意义。 @Tim,在这种情况下你必须通过 System.Drawing.Point.Empty: var absolutePosition = control.PointToScreen(System.Drawing.Point.Empty);【参考方案3】:

我通常结合PointToScreenPointToClient

Point locationOnForm = control.FindForm().PointToClient(
    control.Parent.PointToScreen(control.Location));

【讨论】:

这是REAL ABSOULUTE POSITION ***.com/questions/4998076/… 这与control.PointToScreen(Point.Empty);有何不同? @strongriley 不知道(从未尝试过,目前没有可用的开发环境),但我看不到文档中提到的行为,如果是这样,不能保证它会在未来的框架版本。 @strongriley control.PointToScreen(Point.Empty) 给出了相对于屏幕的位置,而答案给出了与顶层表格相对应的位置。 嘿,你帮了我很多 :) 它将设计的弹出窗口集中在程序显示的中心而不是所有屏幕的中心!【参考方案4】:

在我的测试中,Hans Kesting 和 Fredrik Mörk 的解决方案都给出了相同的答案。但是:

我使用 Raj More 和 Hans Kesting 的方法在答案中发现了一个有趣的差异,并认为我会分享。感谢他们的帮助;我不敢相信框架中没有内置这样的方法。

请注意,Raj 没有编写代码,因此我的实现可能与他的意思不同。

我发现的不同之处在于 Raj More 的方法通常比 Hans Kesting 的方法大两个像素(在 X 和 Y 上)。我还没有确定为什么会发生这种情况。我很确定这与 Windows 窗体的 contents 周围似乎有一个两像素边框的事实有关(例如,在窗体的最外边框内)。在我的测试中,这在任何程度上肯定不是详尽无遗的,我只在嵌套的控件上遇到过它。但是,并非所有嵌套控件都显示它。例如,我在 GroupBox 中有一个 TextBox,它表现出差异,但在同一个 GroupBox 中的一个 Button 没有。我无法解释为什么。

请注意,当答案相同时,他们认为点 (0, 0) 位于我上面提到的内容边框内部。因此,我相信我会认为 Hans Kesting 和 Fredrik Mörk 的解决方案是正确的,但我认为我不会相信我实施的 Raj More 的解决方案。

我还想知道 Raj More 究竟会写什么代码,因为他给出了一个想法但没有提供代码。在阅读这篇文章之前,我并没有完全理解 PointToScreen() 方法:http://social.msdn.microsoft.com/Forums/en-US/netfxcompact/thread/aa91d4d8-e106-48d1-8e8a-59579e14f495

这是我的测试方法。请注意,cmets 中提到的“方法 1”与 Hans Kesting 的略有不同。

private Point GetLocationRelativeToForm(Control c)

  // Method 1: walk up the control tree
  Point controlLocationRelativeToForm1 = new Point();
  Control currentControl = c;
  while (currentControl.Parent != null)
  
    controlLocationRelativeToForm1.Offset(currentControl.Left, currentControl.Top);
    currentControl = currentControl.Parent;
  

  // Method 2: determine absolute position on screen of control and form, and calculate difference
  Point controlScreenPoint = c.PointToScreen(Point.Empty);
  Point formScreenPoint = PointToScreen(Point.Empty);
  Point controlLocationRelativeToForm2 = controlScreenPoint - new Size(formScreenPoint);

  // Method 3: combine PointToScreen() and PointToClient()
  Point locationOnForm = c.FindForm().PointToClient(c.Parent.PointToScreen(c.Location));

  // Theoretically they should be the same
  Debug.Assert(controlLocationRelativeToForm1 == controlLocationRelativeToForm2);
  Debug.Assert(locationOnForm == controlLocationRelativeToForm1);
  Debug.Assert(locationOnForm == controlLocationRelativeToForm2);

  return controlLocationRelativeToForm1;

【讨论】:

【参考方案5】:
private Point FindLocation(Control ctrl)

    if (ctrl.Parent is Form)
        return ctrl.Location;
    else
    
        Point p = FindLocation(ctrl.Parent);
        p.X += ctrl.Location.X;
        p.Y += ctrl.Location.Y;
        return p;
    

【讨论】:

【参考方案6】:

奇怪的是,PointToClient 和 PointToScreen 并不适合我的情况。特别是因为我正在使用与任何表单无关的屏幕外控件。我发现 sahin 的解决方案最有帮助,但去掉了递归并消除了 Form 终止。下面的解决方案适用于我的任何控件是否可见、是否包含表单、是否为 IContainered。谢谢萨希姆。

private static Point FindLocation(Control ctrl)

    Point p;
    for (p = ctrl.Location; ctrl.Parent != null; ctrl = ctrl.Parent)
        p.Offset(ctrl.Parent.Location);
    return p;

【讨论】:

【参考方案7】:

Supergeek,你的非递归函数没有产生正确的结果,但我的。我相信你的添加太多了。

private Point LocationOnClient(Control c)

   Point retval = new Point(0, 0);
   for (; c.Parent != null; c = c.Parent)
    retval.Offset(c.Location); 
   return retval;

【讨论】:

【参考方案8】:

我通常这样做..每次都有效..

var loc = ctrl.PointToScreen(Point.Empty);

【讨论】:

【参考方案9】:

这就是我所做的像魅力一样的工作

            private static int _x=0, _y=0;
        private static Point _point;
        public static Point LocationInForm(Control c)
        
            if (c.Parent == null) 
            
                _x += c.Location.X;
                _y += c.Location.Y;
                _point = new Point(_x, _y);
                _x = 0; _y = 0;
                return _point;
            
            else if ((c.Parent is System.Windows.Forms.Form))
            
                _point = new Point(_x, _y);
                _x = 0; _y = 0;
                return _point;
            
            else 
            
                _x += c.Location.X;
                _y += c.Location.Y;
                LocationInForm(c.Parent);
            
            return new Point(1,1);
        

【讨论】:

以上是关于C#一个普通的类,怎么获取窗体里控件的属性?的主要内容,如果未能解决你的问题,请参考以下文章

C# 获取窗体上控件的位置

C#里怎么在一个窗体里调用另一个窗体的控件

c#的winform,怎么根据控件的名字获取控件属性!

C#获取当前窗体句柄及该窗体里的信息

c#如何创建/设置windows窗体用户控件属性获取简单消息弹窗

C#界面里control.ForeColor 和 control.BackColor 属性的使用