Wpf MVVM:SelectionMode=Extended的列表框绑定,can';如果不选择Changed events(已更改事件),则无法运行此功能
我将在下面发布一些代码,但以下是我尝试执行的操作的摘要: 我有2个视图模型和1个模型:Wpf MVVM:SelectionMode=Extended的列表框绑定,can';如果不选择Changed events(已更改事件),则无法运行此功能,wpf,xaml,mvvm,listbox,Wpf,Xaml,Mvvm,Listbox,我将在下面发布一些代码,但以下是我尝试执行的操作的摘要: 我有2个视图模型和1个模型: ModelData-简单的模型类,只包含一个字符串 ModelDataViewModel-带有可观察集合的ViewModel类 MultipleCollectionsViewModel,具有ObservableCollection的ViewModel类 我有一个“父”列表框,绑定到MultipleCollectionsViewModel。此列表框具有SelectionMode=Extended。每个项表示
- ModelData-简单的模型类,只包含一个字符串
- ModelDataViewModel-带有可观察集合的ViewModel类
- MultipleCollectionsViewModel,具有ObservableCollection的ViewModel类
public class ModelData
{
public ModelData(string id)
{
this.Identifier = id;
}
public string Identifier
{
get;
set;
}
}
以下是ModelDataViewModel
public class ModelDataViewModel : ViewModelBase
{
private ObservableCollection<ModelData> _aClassInstances;
private string name;
public ModelDataViewModel() : this("No-Name") { }
public ModelDataViewModel(string name)
{
this.name = name;
this.ChildItems = new ObservableCollection<ModelData>();
this.ChildItems.Add(new ModelData(Name + "-1"));
this.ChildItems.Add(new ModelData(Name + "-2"));
this.ChildItems.Add(new ModelData(Name + "-3"));
this.AVMIsSelected = false;
}
public ObservableCollection<ModelData> ChildItems
{
get
{
return this._aClassInstances;
}
set
{
this._aClassInstances = value;
this.OnPropertyChanged("ChildItems");
}
}
public string Name
{
get
{
return name;
}
set
{
name = value;
this.OnPropertyChanged("Name");
}
}
private bool isSelected;
public bool AVMIsSelected
{
get
{
return this.isSelected;
}
set
{
this.isSelected = value;
this.OnPropertyChanged("AVMIsSelected");
}
}
}
事实上,这是一个列表框(和数据网格)限制。基本上有两种解决方案:一种使用附加属性,另一种稍微增强ListBox控件并添加缺少的属性。这是一个品味的问题,我更喜欢第二种方式,因为它给了我智能感知的帮助。在XAML中,您使用MultiSelectionListBox
而不是ListBox,并且可以绑定到AllSelectedItems
。请注意,此解决方案仅观察新列表(在视图模型中设置)的更改/分配。当选择更改时,它总是创建一个新列表。如果在视图模型中设置了类型,则是否还要观察可观察集合
,这取决于您的需要
public class MultiSelectionListBox : ListBox
{
public static readonly DependencyProperty AllSelectedItemsProperty = DependencyProperty.Register(
"AllSelectedItems",
typeof(IList),
typeof(MultiSelectionListBox),
new FrameworkPropertyMetadata(null, OnAllSelectedItems));
public MultiSelectionDataGrid()
{
this.SelectionChanged += this.MultiSelectionDataGridSelectionChanged;
}
public IList AllSelectedItems
{
get
{
return (IList)this.GetValue(AllSelectedItemsProperty);
}
set
{
this.SetValue(AllSelectedItemsProperty, value);
}
}
private static void OnAllSelectedItems(object sender, DependencyPropertyChangedEventArgs e)
{
var me = (MultiSelectionListBox)sender;
var newItemList = e.NewValue as IList;
me.SetAllSelectedItems(newItemList);
}
private void MultiSelectionDataGridSelectionChanged(
object sender, SelectionChangedEventArgs e)
{
IEnumerable<object> tempListSrc = this.SelectedItems.Cast<object>();
var tempListDest = new List<object>();
tempListDest.AddRange(tempListSrc.ToList());
this.AllSelectedItems = tempListDest;
}
private void SetAllSelectedItems(IList list)
{
if (list == null)
{
return;
}
this.SelectedItems.Clear();
foreach (object item in list)
{
this.SelectedItems.Add(item);
}
}
}
公共类MultiSelectionListBox:ListBox
{
公共静态只读DependencyProperty AllSelectedItemsProperty=DependencyProperty.Register(
“AllSelectedItems”,
类型(IList),
类型(多选列表框),
新的FrameworkPropertyMetadata(null,OnAllSelectedItems));
公共MultiSelectionDataGrid()
{
this.SelectionChanged+=this.MultiSelectionDataGridSelectionChanged;
}
公共IList AllSelectedItems
{
收到
{
返回(IList)this.GetValue(AllSelectedItemsProperty);
}
设置
{
此.SetValue(AllSelectedItemsProperty,value);
}
}
私有静态无效OnAllSelectedItems(对象发送方,DependencyPropertyChangedEventArgs e)
{
变量me=(MultiSelectionListBox)发送方;
var newItemList=e.NewValue作为IList;
me.SetAllSelectedItems(新项目列表);
}
私有void MultiSelectionDataGridSelectionChanged(
对象发送者,选择ChangedEventArgs(e)
{
IEnumerable tempListSrc=this.SelectedItems.Cast();
var templastdest=新列表();
tempListDest.AddRange(tempListSrc.ToList());
this.AllSelectedItems=templastdest;
}
私有void SetAllSelectedItems(IList列表)
{
if(list==null)
{
回来
}
this.SelectedItems.Clear();
foreach(列表中的对象项)
{
此项。选择编辑项。添加(项);
}
}
}
<Window x:Class="MVVM_Help_Needed.View.SelectedItemSync"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SelectedItemSync" Height="500" Width="600">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<ListBox Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" ItemsSource="{Binding Path=FirstItems}" SelectedItem="{Binding FirstSelectedItem, Mode=TwoWay}" SelectionMode="Extended" SelectionChanged="ListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsSelected" Value="{Binding AVMIsSelected}"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<Button Grid.Column="1" Grid.Row="0" Content="{Binding Path=SelectedItems.Count}"></Button>
<ListBox Grid.Column="1" Grid.Row="1" ItemsSource="{Binding Path=SelectedSubItems}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Identifier}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
public partial class SelectedItemSync : Window
{
public SelectedItemSync()
{
InitializeComponent();
DataContext = new ViewModel.MultipleCollectionsViewModel();
}
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ViewModel.MultipleCollectionsViewModel vm = this.DataContext as ViewModel.MultipleCollectionsViewModel;
vm.SelectedItems = null; // this fires the setter, doesn't actually modify anything.
}
}
public class MultiSelectionListBox : ListBox
{
public static readonly DependencyProperty AllSelectedItemsProperty = DependencyProperty.Register(
"AllSelectedItems",
typeof(IList),
typeof(MultiSelectionListBox),
new FrameworkPropertyMetadata(null, OnAllSelectedItems));
public MultiSelectionDataGrid()
{
this.SelectionChanged += this.MultiSelectionDataGridSelectionChanged;
}
public IList AllSelectedItems
{
get
{
return (IList)this.GetValue(AllSelectedItemsProperty);
}
set
{
this.SetValue(AllSelectedItemsProperty, value);
}
}
private static void OnAllSelectedItems(object sender, DependencyPropertyChangedEventArgs e)
{
var me = (MultiSelectionListBox)sender;
var newItemList = e.NewValue as IList;
me.SetAllSelectedItems(newItemList);
}
private void MultiSelectionDataGridSelectionChanged(
object sender, SelectionChangedEventArgs e)
{
IEnumerable<object> tempListSrc = this.SelectedItems.Cast<object>();
var tempListDest = new List<object>();
tempListDest.AddRange(tempListSrc.ToList());
this.AllSelectedItems = tempListDest;
}
private void SetAllSelectedItems(IList list)
{
if (list == null)
{
return;
}
this.SelectedItems.Clear();
foreach (object item in list)
{
this.SelectedItems.Add(item);
}
}
}