【问题标题】:Is it possible to find which userControl are visible in a flowlayoutPanel是否可以找到在 flowlayoutPanel 中可见的 userControl
【发布时间】:2017-01-23 07:41:18
【问题描述】:

我有一个FlowLayoutPanel,我动态添加了 50 个UserControl。面板垂直放置,每个用户控件都有一些只读标签。

我使用this.KeyPreview = true; 在表单中,这样我就可以使用事件处理程序Form1_KeyUp 来捕获keyUp 事件。 在这个事件处理程序中,我捕获了导航按钮 PageUp PageDown

当我点击导航按钮 时,前一个UserControl 在面板中被选中,当我点击 时,下一个UserControl 被选中。这很好用。

客户还希望能够使用我在前面提到的事件处理程序Form1_KeyUp 中捕获的 PageUpPageDown

我希望我能找到可见的UserControl。假设具有索引 1,2,3,4 的UserControl 在面板中可见,那么当我使用 PageUp 时我可以在索引 1 处选择用户控件,当我单击 时我可以在索引 4 处选择用户控件PageDown.

欢迎任何帮助。

【问题讨论】:

  • 如果可以看到控件的至少一个像素,您的意思是“可见”?
  • 每个控件都有一个 Boolean (get/set) Visible 属性。您可以遍历控件或仅测试 Control.Visible
  • 不是没有,但请花点时间来Tour。接受您认为有帮助的答案并支持问答有助于其他用户找到好的答案。

标签: c# winforms user-controls


【解决方案1】:

你可以使用这样的代码:

var controls = container.Controls.Cast<Control>().OrderBy(x => x.Top);
var visibles = controls.Where(l => container.ClientRectangle.IntersectsWith(l.Bounds));
var top = visibles.FirstOrDefault();
var bottom = visibles.LastOrDefault();

在上面的代码中,我首先通过Top 订购了容器的控件。然后使用IntersectsWith 我发现那些控件的边界与容器的客户矩形相交,这意味着这些控件是可见的。

由于列表是按控件的Top 属性排序的,因此第一项是容器顶部的可见项,最后一项是容器底部的可见项。

注意

  • 您可以使用OfType&lt;YourUserControl&gt;,而不是Cast&lt;Control&gt;
  • 您可以使用OrderByDescending(x =&gt; container.Controls.IndexOf(x)) 而不是OrderBy(x =&gt; x.Top)
  • 您可以使用container.ScrollControlIntoView(top); 或底部控件container.ScrollControlIntoView(bottom); 将顶部控件显示在视图中
  • 如果您有 FlowLayoutPanelAutoScroll=TrueFlowDirection=TopDownWrapContents=False,那么您可以改用 Panel,在添加用户控件时,为它们设置 Dock=Top

【讨论】:

  • 是的,我使用了您建议的代码,我必须添加额外的代码,根据表单的高度在 flowlayoutpanel 中向上或向下导航。
  • @tony 我相信您不需要使用表格高度,而是可以使用此类代码container.ScrollControlIntoView(someControl); someControl 带入视野。这里container 是你的FlowLayoutPanel
  • 顺便说一句,如果您需要的流程是垂直的并且您的FlowLayoutPanel 有滚动条,那么我相信您可以轻松地使用Panel,然后在添加用户控件时,@ 987654345@他们到Top。查看示例here
  • 另外使用FlowLayouPanelAutoScroll=TrueFlowDirection=TopDownWrapContents=False 我可以使用container.ScrollControlIntoView(someControl); 将控件显示在视图中。
【解决方案2】:

如果我理解正确,这就是你的意思

 public List<Control> GetvisibleControls(Control parent)
            {
                List<Control> returnList = new List<Control>();
                foreach(Control child in parent.Controls)
                {
                    if (child.Location.X < parent.Width && child.Location.Y < parent.Height)
                        returnList.Add(child);
                }
                return returnList;
            }

【讨论】:

    【解决方案3】:

    如果您的意思是可见,可见属性为真,请使用“Shannon Holsinger”答案:

    如果您的意思是至少可以看到控件的一个像素,则循环所有控件,并使用此答案检查控件是否可见

    C# winform check if control is physicaly visible

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-10
      • 1970-01-01
      • 2011-01-18
      相关资源
      最近更新 更多