积极答复者
WPF 中的treeview怎样代码展开指定的点呢。

问题
-
<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
答案
-
代码是在WPF-Sample中HierarchicalDataTemplate上直接修改而成
修改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); }