当前位置:  开发笔记 > 编程语言 > 正文

WPF MV-VM:从ListCollectionView中获取所选项目?

如何解决《WPFMV-VM:从ListCollectionView中获取所选项目?》经验,为你挑选了2个好方法。

我有一个使用Model-View-ViewModel模式的WPF应用程序.
在我的ViewModel中,我有一个ListCollectionView来保存项目列表.
此ListCollectionView绑定到我的View中的ListBox.


ListBox的SelectionMode = Multiple,因此您可以一次选择更多项目.现在,ViewModel需要知道选择了哪些项目.

问题是:在View-Model-ViewModel模式中,ViewModel无法访问View,因此我不能只询问ListBox选择了哪些项目.我只有ListCollectionView,但我找不到一种方法来找到那里选择的项目.

那么如何在ListBox中找到已选择的项目?或者实现这一目标的技巧(可能在我的项目中将某些东西绑定到布尔'IsSelected'但是什么?怎么样?)

也许有人正在使用这种模式,可以帮助我吗?



1> 小智..:

您需要创建一个具有IsSelected概念的ViewModel,并绑定到实际ListBoxItem的IsSelected属性,该属性使用标准WPF绑定体系结构在View中表示它.

然后在您的代码中,它知道您的ViewModel,而不是它由任何特定View表示的事实,可以使用该属性来找出模型中的哪些项目实际被选中,而不管设计者如何选择它在视图.



2> surfen..:

PRISM MVVM Reference Implementation有一个名为SynchronizeSelectedItems的行为,在Prism4\MVVM RI\MVVM.Client\Views\MultipleSelectionView.xaml中使用,它将已检查项与名为的ViewModel属性同步Selections:

        

            
                
                
            
            
                
                
            
        

转到http://compositewpf.codeplex.com/并抓住它或使用它:

//===================================================================================
// Microsoft patterns & practices
// Composite Application Guidance for Windows Presentation Foundation and Silverlight
//===================================================================================
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===================================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===================================================================================
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Diagnostics.CodeAnalysis;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;

namespace MVVM.Client.Infrastructure.Behaviors
{
    /// 
    /// Custom behavior that synchronizes the list in  with a collection.
    /// 
    /// 
    /// This behavior uses a weak event handler to listen for changes on the synchronized collection.
    /// 
    public class SynchronizeSelectedItems : Behavior
    {
        public static readonly DependencyProperty SelectionsProperty =
            DependencyProperty.Register(
                "Selections",
                typeof(IList),
                typeof(SynchronizeSelectedItems),
                new PropertyMetadata(null, OnSelectionsPropertyChanged));

        private bool updating;
        private WeakEventHandler currentWeakHandler;

        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
            Justification = "Dependency property")]
        public IList Selections
        {
            get { return (IList)this.GetValue(SelectionsProperty); }
            set { this.SetValue(SelectionsProperty, value); }
        }

        protected override void OnAttached()
        {
            base.OnAttached();

            this.AssociatedObject.SelectionChanged += this.OnSelectedItemsChanged;
            this.UpdateSelectedItems();
        }

        protected override void OnDetaching()
        {
            this.AssociatedObject.SelectionChanged += this.OnSelectedItemsChanged;

            base.OnDetaching();
        }

        private static void OnSelectionsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var behavior = d as SynchronizeSelectedItems;

            if (behavior != null)
            {
                if (behavior.currentWeakHandler != null)
                {
                    behavior.currentWeakHandler.Detach();
                    behavior.currentWeakHandler = null;
                }

                if (e.NewValue != null)
                {
                    var notifyCollectionChanged = e.NewValue as INotifyCollectionChanged;
                    if (notifyCollectionChanged != null)
                    {
                        behavior.currentWeakHandler =
                            new WeakEventHandler(
                                behavior,
                                (instance, sender, args) => instance.OnSelectionsCollectionChanged(sender, args),
                                (listener) => notifyCollectionChanged.CollectionChanged -= listener.OnEvent);
                        notifyCollectionChanged.CollectionChanged += behavior.currentWeakHandler.OnEvent;
                    }

                    behavior.UpdateSelectedItems();
                }
            }
        }

        private void OnSelectedItemsChanged(object sender, SelectionChangedEventArgs e)
        {
            this.UpdateSelections(e);
        }

        private void UpdateSelections(SelectionChangedEventArgs e)
        {
            this.ExecuteIfNotUpdating(
                () =>
                {
                    if (this.Selections != null)
                    {
                        foreach (var item in e.AddedItems)
                        {
                            this.Selections.Add(item);
                        }

                        foreach (var item in e.RemovedItems)
                        {
                            this.Selections.Remove(item);
                        }
                    }
                });
        }

        private void OnSelectionsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            this.UpdateSelectedItems();
        }

        private void UpdateSelectedItems()
        {
            this.ExecuteIfNotUpdating(
                () =>
                {
                    if (this.AssociatedObject != null)
                    {
                        this.AssociatedObject.SelectedItems.Clear();
                        foreach (var item in this.Selections ?? new object[0])
                        {
                            this.AssociatedObject.SelectedItems.Add(item);
                        }
                    }
                });
        }

        private void ExecuteIfNotUpdating(Action execute)
        {
            if (!this.updating)
            {
                try
                {
                    this.updating = true;
                    execute();
                }
                finally
                {
                    this.updating = false;
                }
            }
        }
    }
}


我懒洋洋地说.现在我害怕地颤抖.这就是确定列表框中选择了哪些项目所需的内容?我认为一些建筑师需要死.
推荐阅读
依然-狠幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有