我使用棱镜在SL3应用程序中有一个多选列表框,我需要在我的viewmodel中包含列表框中当前选定的项目的集合。
viewmodel不了解视图,因此无法访问列表框控件。另外,我需要能够从viewmodel中清除列表框中的所选项目。
不知道如何解决这个问题
谢谢
迈克尔
解决方法
因此,假设您有一个具有以下属性的viewmodel:
public ObservableCollection<string> AllItems { get; private set; } public ObservableCollection<string> SelectedItems { get; private set; }
您将首先将AllItems集合绑定到ListBox:
<ListBox x:Name="MyListBox" ItemsSource="{Binding AllItems}" SelectionMode="Multiple" />
问题是ListBox上的SelectedItems属性不是DependencyProperty。这是非常糟糕的,因为您无法将其绑定到viewmodel中的某个东西。
第一种方法是将这个逻辑放在代码隐藏中,调整viewmodel:
public MainPage() { InitializeComponent(); MyListBox.SelectionChanged += ListBoxSelectionChanged; } private static void ListBoxSelectionChanged(object sender,SelectionChangedEventArgs e) { var listBox = sender as ListBox; if(listBox == null) return; var viewmodel = listBox.DataContext as MainVM; if(viewmodel == null) return; viewmodel.SelectedItems.Clear(); foreach (string item in listBox.SelectedItems) { viewmodel.SelectedItems.Add(item); } }
这种做法会奏效,但真的很丑陋。我的首选方法是将此行为提取为“附加行为”。如果您这样做,您可以完全消除您的代码隐藏并将其设置在XAML中。奖金是这个“附加行为”现在可以在任何ListBox中重用:
<ListBox ItemsSource="{Binding AllItems}" Demo:SelectedItems.Items="{Binding SelectedItems}" SelectionMode="Multiple" />
这里是附加行为的代码:
public static class SelectedItems { private static readonly DependencyProperty SelectedItemsBehaviorProperty = DependencyProperty.Registerattached( "SelectedItemsBehavior",typeof(SelectedItemsBehavior),typeof(ListBox),null); public static readonly DependencyProperty ItemsProperty = DependencyProperty.Registerattached( "Items",typeof(IList),typeof(SelectedItems),new PropertyMetadata(null,ItemsPropertyChanged)); public static void SetItems(ListBox listBox,IList list) { listBox.SetValue(ItemsProperty,list); } public static IList GetItems(ListBox listBox) { return listBox.GetValue(ItemsProperty) as IList; } private static void ItemsPropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e) { var target = d as ListBox; if (target != null) { GetorCreateBehavior(target,e.NewValue as IList); } } private static SelectedItemsBehavior GetorCreateBehavior(ListBox target,IList list) { var behavior = target.GetValue(SelectedItemsBehaviorProperty) as SelectedItemsBehavior; if (behavior == null) { behavior = new SelectedItemsBehavior(target,list); target.SetValue(SelectedItemsBehaviorProperty,behavior); } return behavior; } } public class SelectedItemsBehavior { private readonly ListBox _listBox; private readonly IList _boundList; public SelectedItemsBehavior(ListBox listBox,IList boundList) { _boundList = boundList; _listBox = listBox; _listBox.SelectionChanged += OnSelectionChanged; } private void OnSelectionChanged(object sender,SelectionChangedEventArgs e) { _boundList.Clear(); foreach (var item in _listBox.SelectedItems) { _boundList.Add(item); } } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。