gpt4 book ai didi

silverlight-3.0 - 将多选列表框中的 SelectedItems 与 ViewModel 中的集契约(Contract)步

转载 作者:行者123 更新时间:2023-12-03 12:03:08 24 4
gpt4 key购买 nike

我在使用 prism 的 SL3 应用程序中有一个多选列表框,并且我的 View 模型中需要一个集合,其中包含列表框中当前选定的项目。

viewmodel 对 View 一无所知,因此它无权访问列表框控件。此外,我需要能够从 View 模型中清除列表框中的选定项目。

不知道如何解决这个问题

谢谢
迈克尔

最佳答案

因此,假设您有一个具有以下属性的 ViewModel:

public ObservableCollection<string> AllItems { get; private set; }
public ObservableCollection<string> SelectedItems { get; private set; }

首先将 AllItems 集合绑定(bind)到 ListBox:
<ListBox x:Name="MyListBox" ItemsSource="{Binding AllItems}" SelectionMode="Multiple" />

问题是 ListBox 上的 SelectedItems 属性不是 DependencyProperty。这很糟糕,因为您无法将其绑定(bind)到 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);
}
}
}

关于silverlight-3.0 - 将多选列表框中的 SelectedItems 与 ViewModel 中的集契约(Contract)步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1297643/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com