在WPF中,不论是ListBox,ListView或者DataGrid,在使用中都会经常用到SelectedItems,但是在Xaml中却发现SelectedItems没有办法Binding。这是因为SelectedItems是一个只读属性,且不是一个DependencyProperty,所以没法Binding。不过我们却可以通过以下几种方法来实现这个功能:
【方案一】
使用后台代码,读取这个控件的SelectedItems属性。例如 XAML:
1 2 <ListView ItemsSource ="{Binding}" x:Name ="lvTest" > </ListView >
那么后台就可以
1 2 3 4 foreach (XX item in lvTest.SelectedItems){ }
如果列表控件是作为ControlTemplate的内容,那么就在后台获取ControlTemplate下的这个控件
1 var lvTest= XX.Template.FindName("lvTest" , XX);
【方案二】
可以通过修改SelectionChanged事件来通知后台该控件选择的项。MSDN 中提供了这一解决方案。
XAML
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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 <Window x:Class ="ListViewSelectedItemsBinding.Window1" xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local ="clr-namespace:ListViewSelectedItemsBinding" xmlns:w ="clr-namespace:System.Windows.Workarounds" x:Name ="root" Width ="500" Height ="700" ><Window.Resources > <local:MyConverter x:Key ="myConverter" /> </Window.Resources > <StackPanel > <ListView x:Name ="listView" ItemsSource ="{Binding}" SelectionMode ="Extended" SelectionChanged ="listView_SelectionChanged" w:ListView.HasBindableSelectedItems ="True" ><ListView.View > <GridView > <GridViewColumn Header ="Artist" DisplayMemberBinding ="{Binding Path=Artist}" /> <GridViewColumn Header ="Title" DisplayMemberBinding ="{Binding Path=Title}" /> <GridViewColumn Header ="Genre" DisplayMemberBinding ="{Binding Path=Genre}" /> </GridView > </ListView.View > </ListView > <StackPanel Background ="LightGreen" > <DockPanel > <Label DockPanel.Dock ="Left" Content ="SelectedItems.Count = " /> <TextBox Text ="{Binding ElementName=listView, Path=SelectedItems.Count, Mode=OneWay}" IsReadOnly ="True" /> </DockPanel > <DockPanel > <Label DockPanel.Dock ="Left" Content ="SelectedItems = " /> <TextBox Text ="{Binding ElementName=listView, Path=SelectedItems, Mode=OneWay, Converter={StaticResource myConverter}, ConverterParameter='Artist'}" IsReadOnly ="True" /></DockPanel > </StackPanel > <StackPanel Background ="LightBlue" > <DockPanel > <Label DockPanel.Dock ="Left" Content ="Selection.Count = " /> <TextBox Text ="{Binding ElementName=root, Path=Selection.Count, Mode=OneWay}" IsReadOnly ="True" /> </DockPanel > <DockPanel > <Label DockPanel.Dock ="Left" Content ="Selection = " /> <TextBox Text ="{Binding ElementName=root, Path=Selection, Mode=OneWay, Converter={StaticResource myConverter}, ConverterParameter='Artist'}" IsReadOnly ="True" /></DockPanel > </StackPanel > <local:PropertiesPanel x:Name ="propertiesPanel1" Background ="LightGreen" Subjects ="{Binding ElementName=listView, Path=SelectedItems, Mode=OneWay}" /><local:PropertiesPanel x:Name ="propertiesPanel2" Background ="LightBlue" Subjects ="{Binding ElementName=root, Path=Selection, Mode=OneWay}" /><local:PropertiesPanel x:Name ="propertiesPanel3" Background ="LightPink" Subjects ="{Binding ElementName=listView, Path=BindableSelectedItems}" /></StackPanel > </Window >
后台
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 using System;using System.Collections;using System.Windows.Data;using System.Windows.Controls;namespace System.Windows.Workarounds { public static class ListView { public static readonly DependencyProperty HasBindableSelectedItemsProperty; public static readonly DependencyProperty BindableSelectedItemsProperty; static DependencyProperty SelectionChangedHandlerProperty; static ListView () { BindableSelectedItemsProperty = DependencyProperty.Register("BindableSelectedItems" , typeof (IList), typeof (System.Windows.Controls.ListView)); HasBindableSelectedItemsProperty = DependencyProperty.RegisterAttached("HasBindableSelectedItems" , typeof (bool ), typeof (System.Windows.Controls.ListView), new PropertyMetadata(false )); SelectionChangedHandlerProperty = DependencyProperty.RegisterAttached("SelectionChangedHandler" , typeof (SelectionChangedHandler), typeof (System.Windows.Controls.ListView)); } public static void SetHasBindableSelectedItems (System.Windows.Controls.ListView source, bool value ) { SelectionChangedHandler Handler = (SelectionChangedHandler)source.GetValue(SelectionChangedHandlerProperty); if (value && Handler == null ) { Handler = new SelectionChangedHandler(source); source.SetValue(SelectionChangedHandlerProperty, Handler); } else if (!value && Handler != null ) { source.ClearValue(SelectionChangedHandlerProperty); } } } internal class SelectionChangedHandler { Binding Binding; internal SelectionChangedHandler (System.Windows.Controls.ListView owner ) { Binding = new Binding("SelectedItems" ); Binding.Source = owner; owner.SetBinding(ListView.BindableSelectedItemsProperty, Binding); owner.SelectionChanged += new SelectionChangedEventHandler(Owner_SelectionChanged); } void Owner_SelectionChanged (object sender, SelectionChangedEventArgs e ) { System.Windows.Controls.ListView Owner = (System.Windows.Controls.ListView)sender; BindingOperations.ClearBinding(Owner, ListView.BindableSelectedItemsProperty); Owner.SetBinding(ListView.BindableSelectedItemsProperty, Binding); } } }
【方案三】
可以重写SelectedItems实现Binding,方案可以参考这里