none
WPF 中的treeview怎样代码展开指定的点呢。 RRS feed

  • 问题

  • <Window x:Class="DataBinding.BoundTreeView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="BoundTreeView" Height="300" Width="300"
        xmlns:data="clr-namespace:StoreDatabase;assembly=StoreDatabase"
        >
      <Window.Resources>
        <HierarchicalDataTemplate DataType="{x:Type data:Category}"
                                    ItemsSource="{Binding Path=Products}">
          <TextBlock Text="{Binding Path=CategoryName}"/>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="{x:Type data:Product}"      >
          <TextBlock Text="{Binding Path=ModelName}" />      
        </HierarchicalDataTemplate>
        
      </Window.Resources>
      <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="auto"/>
                <ColumnDefinition Width="auto"/>
            </Grid.ColumnDefinitions>  
            <TreeView Name="treeCategories" Margin="5">
          
            </TreeView>
            <Button Width="40" Height="20" Grid.Column="1" Click="Button_Click"></Button>
      </Grid>
    </Window>

    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    
    namespace DataBinding
    {
        /// <summary>
        /// Interaction logic for BoundTreeView.xaml
        /// </summary>
    
        public partial class BoundTreeView : System.Windows.Window
        {
    
            public BoundTreeView()
            {
                InitializeComponent();
    
                treeCategories.ItemsSource = App.StoreDb.GetCategoriesAndProducts();
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                
            
            }
        }
    }

    我希望点击右边的按钮能够展开指定的树节点,用的是HierarchicalDataTemplate的方式,就不知道咋做了。


    • 已编辑 彭123 2019年8月2日 9:54
    2019年8月2日 9:53

答案

  • 代码是在WPF-SampleHierarchicalDataTemplate上直接修改而成

    修改xaml

        <DockPanel>
            <DockPanel.Resources>
                <local:ListLeagueList x:Key="MyList"/>
    
                <HierarchicalDataTemplate DataType    = "{x:Type local:League}"
                                    ItemsSource = "{Binding Path=Divisions}">
                    <TextBlock Text="{Binding Path=Name}"/>
                </HierarchicalDataTemplate>
    
                <HierarchicalDataTemplate DataType    = "{x:Type local:Division}"
                                    ItemsSource = "{Binding Path=Teams}">
                    <TextBlock Text="{Binding Path=Name}"/>
                </HierarchicalDataTemplate>
    
                <DataTemplate DataType="{x:Type local:Team}">
                    <TextBlock Text="{Binding Path=Name}"/>
                </DataTemplate>
            </DockPanel.Resources>
    
            <Menu Name="menu1" DockPanel.Dock="Top" Margin="10,10,10,10">
                <MenuItem Header="My Soccer Leagues"
                      ItemsSource="{Binding Source={StaticResource MyList}}" />
            </Menu>
    
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="auto"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <StackPanel Orientation="Horizontal">
                    <TextBox Width="50" x:Name="serach"/>
                    <Button Content="搜索" x:Name="S_btn" Click="S_btn_Click"/>
                </StackPanel>
                <TreeView x:Name="TV" Grid.Row="1">
                    <TreeView.ItemContainerStyle>
                        <Style TargetType="TreeViewItem">
                            <Setter Property="IsExpanded" Value="{Binding  IsItemOpen,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"/>
                            <Style.Triggers>
                                <Trigger Property="IsExpanded" Value="true">
                                    <Setter Property="Background" Value="Red"/>
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </TreeView.ItemContainerStyle>
                </TreeView>
            </Grid>
    
        </DockPanel>


    在定义的集合中编写一个bool值作为TreeViewItem是否展开的判断

    添加类IsOpen

    public class IsOpen : INotifyPropertyChanged { protected void OnPropertyChanged([CallerMemberName] string name = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } public event PropertyChangedEventHandler PropertyChanged; private bool _isopen; public bool IsItemOpen { get => _isopen; set { _isopen = value; OnPropertyChanged(); } } }

    并让Division,League,Team均继承IsOpen

    关键是编写TreeView的ItemContainerStyle

     <TreeView.ItemContainerStyle>
                        <Style TargetType="TreeViewItem">
                            <Setter Property="IsExpanded" Value="{Binding  IsItemOpen,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"/>
                         </Style>
     </TreeView.ItemContainerStyle>

    之后就是编写查找相关数据的节点,并修改IsItemOpen

     private void OpenExpandAtLastIndexName(string Name)
            {
                var item = from p in leagues
                           from c in p.Divisions
                           from o in c.Teams
                           where o.Name.Equals(Name)
                           select c;
    
                var p1 = item.ToList();
    
                foreach (var q in p1)
                {
                    q.IsItemOpen = true;
                    var b = leagues.FindAll(y => y.Divisions.FindAll(h => h.Equals(q)) != null);
                    foreach (var g in b)
                    {  
                        var f = g.Divisions.FindAll(h => h.Equals(q));
                        foreach (var r in f)
                        {
                            var bs= g.Divisions.Find(s => s.Equals(r));
                            if (bs != null)
                                g.IsItemOpen = true;
                        }
                    }
                }
            }

    其他cs部分:

         ListLeagueList leagues = new ListLeagueList();
            public MainWindow()
            {
                InitializeComponent();
               
                TV.ItemsSource = leagues;
                
            }

    button代码

     private void S_btn_Click(object sender, RoutedEventArgs e)
            {
                OpenExpandAtLastIndexName(serach.Text);
            }


    • 已编辑 ARM830 2019年8月3日 3:01
    • 已标记为答案 彭123 2019年8月4日 15:44
    2019年8月3日 2:55