微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

silverlight-3.0 – 使用ViewModel中的集合在Muliselect列表框中同步SelectedItem

我使用棱镜在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] 举报,一经查实,本站将立刻删除。

相关推荐