【问题标题】:List all controls of a specific window of WPF列出WPF特定窗口的所有控件
【发布时间】:2017-03-30 14:58:56
【问题描述】:

我对 WPF 很陌生,只是想请你帮忙,以获取一种非常基本的方法来获取 Windows 控件及其子项,就像在 Winform 应用程序中一样。底线是为不同类中的多个窗口/页面提供可重用的代码。

之前非常感谢。

Public Sub GetControl(Wn As Window)
    For Each Ctrl As Control In Wn.Controls
        'Code here

        If Ctrl.HasChildren = True Then
            'Code here
        End If
    Next
End Sub

【问题讨论】:

标签: wpf vb.net xaml


【解决方案1】:

所以这里是低点。您需要查找 UIElement,它是 XAML 中所有 UIElement 的基类。主机控件有两种主要类型。内容控制和面板。
ContentControl 具有可能包含对象的“内容”属性。 Panel 具有 UIElements 属性“Children”和 UIElement 类型的集合。

如果您只是在寻找 Window 或 ANY UIElement 的元素,那么您需要递归搜索并根据该信息创建该列表。

Window 继承自 ContentControl,但该 Content 可能是 Grid 或 StackPanel 或任何 Panel 或排序,并且还可能具有 UIElement 的子级。

你循环遍历它们直到你得到结果。

public MainWindow()
{
        InitializeComponent();

        foreach (var element in GetAllElementsFrom(this))
            Debug.WriteLine(element.ToString());
}

private IEnumerable<UIElement> GetAllElementsFrom(UIElement element)
{
    var uiElements = GetSingleElement();

       switch (element)
       {
            case Panel panel:
                foreach (var child in panel.Children)
                    uiElements = uiElements.Concat(GetInnerElements(child));
                break;
            case UserControl userControl:
                uiElements = uiElements.Concat(GetInnerElements(userControl.Content));
                break;
            case ContentControl contentControl:
                if (contentControl.Content is UIElement uiElement)
                    uiElements = uiElements.Concat(GetInnerElements(uiElement));
                break;
        }

    return uiElements;

    IEnumerable<UIElement> GetSingleElement()
    {
        yield return element;
    }
}

这是我使用的 XAML。

<Grid>
    <Button>
        <DockPanel>
            <ContentControl>
                <Grid>
                    <TextBox />
                </Grid>
            </ContentControl>
        </DockPanel>
    </Button>

    <StackPanel>
        <Label />
        <TextBlock>
            Hey There!!
        </TextBlock>
        <Grid>
            <Ellipse />
        </Grid>
    </StackPanel>
</Grid>

这是我在调试窗口中得到的结果:

System.Windows.Controls.Grid
System.Windows.Controls.Button
System.Windows.Controls.DockPanel
System.Windows.Controls.ContentControl
System.Windows.Controls.Grid
System.Windows.Controls.TextBox
System.Windows.Controls.StackPanel
System.Windows.Controls.Label
System.Windows.Controls.TextBlock
System.Windows.Controls.Grid
System.Windows.Shapes.Ellipse

编码愉快!注意:使用 C# 7 语法;如果您不在 C# 7 上,那么只需进行更改,我认为它们是直截了当的。

【讨论】:

  • 虽然 C# 7 语法更简洁,但 OP 声明“我对 WPF 很陌生”,因此它可能不是回答问题的最佳方式。不管怎样,谢谢你的回答。
  • @GregMulvihill 很抱歉,但我想我已经详细介绍了答案,以便您理解。不管 C# 7 语法如何,C# 7 与 WPF 无关。
  • @GregMulvihill 但是;我确实看到您编写的示例是 VB.NET 而不是 C#,所以我很抱歉。但是,两者都使用相同的概念。只需阅读遍历元素的描述。你可以在 VB.NET 中做同样的事情,如果你愿意,我会在 VB 中更新答案。
  • 你应该留下你贡献的东西,它是 C# 7 的一个很好的例子......如果你觉得有必要,添加一个 VB.NET 版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-15
  • 2020-02-20
  • 1970-01-01
  • 1970-01-01
  • 2013-01-14
  • 1970-01-01
相关资源
最近更新 更多