为了账号安全,请及时绑定邮箱和手机立即绑定

如何按类型获取WPF容器的子项?

如何按类型获取WPF容器的子项?

C#
暮色呼如 2019-08-09 10:28:55
如何按类型获取WPF容器的子项?我怎样才能类型的子控件ComboBox中MyContainer Grid的WPF?<Grid x:Name="MyContainer">                         <Label Content="Name"  Name="label1"  />     <Label Content="State" Name="label2"  />     <ComboBox Height="23" HorizontalAlignment="Left" Name="comboBox1"/>     <ComboBox Height="23" HorizontalAlignment="Left" Name="comboBox3" />     <ComboBox Height="23" HorizontalAlignment="Left" Name="comboBox4" /></Grid>这行给了我一个错误:var myCombobox = this.MyContainer.Children.GetType(ComboBox);
查看完整描述

3 回答

?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

儿童是UIElements的集合。因此,您需要迭代项目并确定每个项目是否属于所需类型。幸运的是,已经有一个Linq方法就是这样,即Enumerable.OfType<T>可以使用Extension Method语法方便地调用它:

var comboBoxes = this.MyContainer.Children.OfType<ComboBox>();

此方法根据类型过滤集合,并在您的情况下仅返回类型的元素ComboBox

如果您只想要第一个ComboBox(如您的变量名可能建议的那样),您只需追加FirstOrDefault()对查询的调用:

var myComboBox = this.MyContainer.Children.OfType<ComboBox>().FirstOrDefault();


查看完整回答
1 反对 回复 2019-08-09
?
拉莫斯之舞

TA贡献1820条经验 获得超10个赞

此扩展方法将递归搜索所需类型的子元素:

public static T GetChildOfType<T>(this DependencyObject depObj) 
    where T : DependencyObject{
    if (depObj == null) return null;

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
    {
        var child = VisualTreeHelper.GetChild(depObj, i);

        var result = (child as T) ?? GetChildOfType<T>(child);
        if (result != null) return result;
    }
    return null;}

所以使用它你可以要求MyContainer.GetChildOfType<ComboBox>()


查看完整回答
反对 回复 2019-08-09
?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

所有这些答案,但一个使用递归,IMO只是跛脚:)

获得视觉孩子:

public static IEnumerable<T> FindVisualChildren<T>([NotNull] this DependencyObject parent) where T : DependencyObject{
    if (parent == null)
        throw new ArgumentNullException(nameof(parent));

    var queue = new Queue<DependencyObject>(new[] {parent});

    while (queue.Any())
    {
        var reference = queue.Dequeue();
        var count = VisualTreeHelper.GetChildrenCount(reference);

        for (var i = 0; i < count; i++)
        {
            var child = VisualTreeHelper.GetChild(reference, i);
            if (child is T children)
                yield return children;

            queue.Enqueue(child);
        }
    }}

让逻辑儿童:

public static IEnumerable<T> FindLogicalChildren<T>([NotNull] this DependencyObject parent) where T : DependencyObject{
    if (parent == null)
        throw new ArgumentNullException(nameof(parent));

    var queue = new Queue<DependencyObject>(new[] {parent});

    while (queue.Any())
    {
        var reference = queue.Dequeue();
        var children = LogicalTreeHelper.GetChildren(reference);
        var objects = children.OfType<DependencyObject>();

        foreach (var o in objects)
        {
            if (o is T child)
                yield return child;

            queue.Enqueue(o);
        }
    }}

注意,这两个深遍历树,如果你想停止在第一次相遇,然后同时更改代码调用包括对queue.Enqueueelse块。


查看完整回答
反对 回复 2019-08-09
  • 3 回答
  • 0 关注
  • 703 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信