代码之家  ›  专栏  ›  技术社区  ›  polfosol à° _à°

如何访问WPF GroupItem模板中的元素

  •  -1
  • polfosol à° _à°  · 技术社区  · 6 年前

    我有一个 ListView 里面装满了一些东西。这些项目有两个属性, ItemName ItemGroup

    <Grid>
        <Grid.Resources>
            <Style x:Key="groupStyle" TargetType="{x:Type GroupItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Expander IsExpanded="False" Header="{Binding Name}">
                                <ItemsPresenter />
                            </Expander>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Grid.Resources>
        <ListView x:Name="lv">
            <ListView.View>
                <GridView>
                    <GridViewColumn>
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding ItemName}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
            <ListView.GroupStyle>
                <GroupStyle ContainerStyle="{StaticResource groupStyle}"/>
            </ListView.GroupStyle>
        </ListView>
    </Grid>
    

    在后面的代码里

    // here, list is the collection of items with mentioned properties.
    lv.ItemsSource = list;
    var view = (CollectionView) CollectionViewSource.GetDefaultView(lv.ItemsSource);
    if (view.GroupDescriptions != null)
    {
        view.GroupDescriptions.Clear();
        view.GroupDescriptions.Add(new PropertyGroupDescription("ItemGroup"));
    }
    

    现在一切顺利。但问题是,有时我想把 Expander IsExpanded 属性设置为true。我该怎么做?

    编辑 :下面是我用来查找扩展器的方法,例如。 FindChildren<Expander>(lv) 但它总是返回一个空集合

    public static IEnumerable<T> FindChildren<T>(DependencyObject obj) where T : DependencyObject
    {
        if (obj == null)
        {
            yield break;
        }
        int vt_count = obj is Visual ? VisualTreeHelper.GetChildrenCount(obj) : 0;
        var children = vt_count > 0
            ? Enumerable.Range(0, vt_count).Select(n => VisualTreeHelper.GetChild(obj, n))
            : LogicalTreeHelper.GetChildren(obj).OfType<DependencyObject>();
    
        foreach (var child in children)
        {
            if (child is T)
            {
                yield return (T) child;
                continue;
            }
            foreach (T descendant in FindChildren<T>(child))
                yield return descendant;
        }
    }
    
    2 回复  |  直到 5 年前
        1
  •  1
  •   mm8    6 年前

    Expander 使用递归方法和 VisualTreeHelper 班级:

    private void ExpandButton_Click(object sender, RoutedEventArgs e)
    {
        foreach (Expander gi in FindVisualChildren<Expander>(lv))
        {
            gi.IsExpanded = true;
        }
    }
    
    private static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    yield return (T)child;
                }
    
                foreach (T childOfChild in FindVisualChildren<T>(child))
                {
                    yield return childOfChild;
                }
            }
        }
    }
    

    编辑: 如果你想在设置好 ItemsSource ListView ,您需要等待容器创建完毕。处理 Loaded

    public MainWindow()
    {
        InitializeComponent();
    
        // here, list is the collection of items with mentioned properties.
        lv.ItemsSource = list;
        var view = (CollectionView)CollectionViewSource.GetDefaultView(lv.ItemsSource);
        if (view.GroupDescriptions != null)
        {
            view.GroupDescriptions.Clear();
            view.GroupDescriptions.Add(new PropertyGroupDescription("ItemGroup"));
        }
    
        Loaded += (s, e) =>
        {
            foreach (Expander gi in FindVisualChildren<Expander>(lv))
            {
                gi.IsExpanded = true;
            }
        };
    }
    
        2
  •  0
  •   polfosol à° _à°    6 年前

    奇怪地 ,由@mm8发布的答案不起作用,我也不知道为什么。但不管怎样,我还是设法解决了这个问题。关键是绑定 IsExpanded 扩展程序的属性转换为 ListView ,例如其标签:

    <ControlTemplate>
        <Expander Header="{Binding Name}">
            <Expander.IsExpanded>
                <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=ListView}" Path="Tag" />
            </Expander.IsExpanded>
            <ItemsPresenter />
        </Expander>
    </ControlTemplate>
    

    然后你就可以控制 I扩展 lv.Tag = true; lv.Tag = false; 在密码里。