MVVM处理TreeView的SelectedItem的绑定的两种方式
TreeView的SelectedItem不支持MVVM绑定:
因为它是只读的。
有时候我们就需要对它进行绑定
1.使用自定义Behavior
需要引用System.Windows.Interactivity.dll
自定义Behavior如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | public class TreeViewBehavior : Behavior<TreeView> { public object SelectedItem { get { return ( object )GetValue(SelectedItemProperty); } set { SetValue(SelectedItemProperty, value); } } // Using a DependencyProperty as the backing store for SelectedItem. This enables animation, styling, binding, etc... public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register( "SelectedItem" , typeof ( object ), typeof (TreeViewBehavior), new PropertyMetadata( null , OnSelectedItemChanged)); private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var treeViewHelper = d as TreeViewBehavior; SetItemSelected(treeViewHelper.AssociatedObject, e.NewValue); } private static void SetItemSelected(TreeView tree, object context) { for ( int i = 0; i < tree.Items.Count; i++) { var treeItem = tree.ItemContainerGenerator.ContainerFromIndex(i) as TreeViewItem; if (SetItemSelected(treeItem,context)) { return ; } } } private static bool SetItemSelected(TreeViewItem treeViewItem, object datacontext) { if (treeViewItem.DataContext == datacontext) { treeViewItem.IsSelected = true ; return true ; } for ( int i = 0; i < treeViewItem.Items.Count; i++) { var subTreeViewItem = treeViewItem.ItemContainerGenerator.ContainerFromIndex(i) as TreeViewItem; if (subTreeViewItem != null && subTreeViewItem.DataContext == datacontext) { subTreeViewItem.IsSelected = true ; return true ; } } return false ; } protected override void OnAttached() { base .OnAttached(); this .AssociatedObject.SelectedItemChanged += AssociatedObject_Selected; } private void AssociatedObject_Selected( object sender, System.Windows.RoutedEventArgs e) { var treeView = sender as TreeView; this .SelectedItem = treeView?.SelectedItem; } protected override void OnDetaching() { base .OnDetaching(); this .AssociatedObject.SelectedItemChanged -= AssociatedObject_Selected; } } |
前台使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <Grid> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <TreeView ItemsSource= "{Binding Nodes}" > <TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource= "{Binding Children}" > <Grid> <TextBlock Text= "{Binding Name}" ></TextBlock> </Grid> </HierarchicalDataTemplate> </TreeView.ItemTemplate> <i:Interaction.Behaviors> <local:TreeViewBehavior SelectedItem= "{Binding SelectedItem,Mode=TwoWay}" ></local:TreeViewBehavior> </i:Interaction.Behaviors> </TreeView> <Label Grid.Column= "1" Content= "{Binding SelectedItem.Name}" ></Label> <Button Grid.Column= "1" Margin= "100" Click= "Button_Click" ></Button> </Grid> |
2.使用附加属性和注册类的路由事件
附加属性及类的路由事件处理逻辑如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | class TreeViewHelper { static TreeViewHelper() { EventManager.RegisterClassHandler( typeof (TreeView), TreeView.SelectedItemChangedEvent, new RoutedEventHandler(OnSeletedItemChanged)); } public static object GetSelectedItem(DependencyObject obj) { return ( object )obj.GetValue(SelectedItemProperty); } public static void SetSelectedItem(DependencyObject obj, object value) { obj.SetValue(SelectedItemProperty, value); } // Using a DependencyProperty as the backing store for SelectedItem. This enables animation, styling, binding, etc... public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.RegisterAttached( "SelectedItem" , typeof ( object ), typeof (TreeViewHelper), new PropertyMetadata( null ,OnSelectedItemChanged)); private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { SetItemSelected(d as TreeView, e.NewValue); } private static void SetItemSelected(TreeView tree, object context) { for ( int i = 0; i < tree.Items.Count; i++) { var treeItem = tree.ItemContainerGenerator.ContainerFromIndex(i) as TreeViewItem; if (SetItemSelected(treeItem, context)) { return ; } } } private static bool SetItemSelected(TreeViewItem treeViewItem, object datacontext) { if (treeViewItem.DataContext == datacontext) { treeViewItem.IsSelected = true ; return true ; } for ( int i = 0; i < treeViewItem.Items.Count; i++) { var subTreeViewItem = treeViewItem.ItemContainerGenerator.ContainerFromIndex(i) as TreeViewItem; if (subTreeViewItem != null && subTreeViewItem.DataContext == datacontext) { subTreeViewItem.IsSelected = true ; return true ; } } return false ; } private static void OnSeletedItemChanged( object sender, RoutedEventArgs e) { var treeView = sender as TreeView; SetSelectedItem(treeView,treeView.SelectedItem); } } |
前台代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <Window x:Class= "WPF_TreeViewTest.MainWindow" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x= "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d= "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc= "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local= "clr-namespace:WPF_TreeViewTest" mc:Ignorable= "d" Title= "MainWindow" Height= "450" Width= "800" > <Grid> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <TreeView ItemsSource= "{Binding Nodes}" local:TreeViewHelper.SelectedItem= "{Binding SelectedItem,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" > <TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource= "{Binding Children}" > <Grid> <TextBlock Text= "{Binding Name}" ></TextBlock> </Grid> </HierarchicalDataTemplate> </TreeView.ItemTemplate> </TreeView> <Label Grid.Column= "1" Content= "{Binding SelectedItem.Name}" ></Label> <Button Grid.Column= "1" Margin= "100" Click= "Button_Click" ></Button> </Grid> </Window> |
————————————————
版权声明:本文为CSDN博主「lishuangquan1987」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lishuangquan1987/article/details/115305335
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步