使用MVVM模式在Telerik RadGridView中查找选定项

使用MVVM模式在Telerik RadGridView中查找选定项,mvvm,telerik,selecteditem,caliburn.micro,radgridview,Mvvm,Telerik,Selecteditem,Caliburn.micro,Radgridview,我在我的应用程序中使用了Telerik RadGridView,它有一个GridViewSelectColumn项,允许我选择网格中的各种项目。我有一个按钮可以操作这个选择,但不知道如何获得所选项目的列表。问题是我在Caliburn.Micro中使用了MVVM模式。我是否需要在视图中找到控件并遍历所选项目的列表?对于一项简单的任务来说,这似乎是一项艰巨的任务。如果您有任何想法,我将不胜感激。为您的收藏中的物品添加一个选择: public class Customer {

我在我的应用程序中使用了Telerik RadGridView,它有一个GridViewSelectColumn项,允许我选择网格中的各种项目。我有一个按钮可以操作这个选择,但不知道如何获得所选项目的列表。问题是我在Caliburn.Micro中使用了MVVM模式。我是否需要在视图中找到控件并遍历所选项目的列表?对于一项简单的任务来说,这似乎是一项艰巨的任务。如果您有任何想法,我将不胜感激。

为您的收藏中的物品添加一个选择:

 public class Customer
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public bool IsSelected { get; set; }
    }

 private BindableCollection<Customer> _customers;
        public BindableCollection<Customer> Customers
        {
            get { return _customers; }
            set
            {
                _customers = value;
                NotifyOfPropertyChange(() => Customers);
            }
        }
公共类客户
{
公共int Id{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共布尔值被选为{get;set;}
}
私人BindableCollection\u客户;
公共BindableCollection客户
{
获取{return\u customers;}
设置
{
_顾客=价值;
通知财产变更(()=>客户);
}
}


在某些情况下,您无法添加布尔值(例如ObseravbleCollection)


请看一看解决方案。

Telerik的RadGridView的问题是,它的SelectedItem集合是只读的,因此无法将双向绑定到SelectedItems

解决方法是使用自定义行为在RadGridView和ViewModels SelectedItem集合之间进行同步

您可以使用以下行为:

// Behavior for synchronizing a RadDataGrid's SelectedItems collection with a SelectedItems collection of the ViewModel (the Network)
// The problem is, that RadDataGrid.SelectedItems is a read-only collection and therefore cannot be used for two-way binding.

class SelectedSyncBehavior
    : Behavior<RadGridView>
{
    bool _collectionChangedSuspended = false;

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.SelectedItems.CollectionChanged += GridSelectedItems_CollectionChanged;
    }

    /// <summary>
    /// Getter/Setter for DependencyProperty, bound to the DataContext's SelectedItems ObservableCollection
    /// </summary>
    public INotifyCollectionChanged SelectedItems
    {
        get { return (INotifyCollectionChanged)GetValue(SelectedItemsProperty); }
        set { SetValue(SelectedItemsProperty, value); }
    }

    /// <summary>
    /// Dependency Property "SelectedItems" is target of binding to DataContext's SelectedItems
    /// </summary>
    public static readonly DependencyProperty SelectedItemsProperty =
        DependencyProperty.Register("SelectedItems", typeof(INotifyCollectionChanged), typeof(SelectedSyncBehavior), new PropertyMetadata(OnSelectedItemsPropertyChanged));

    /// <summary>
    /// PropertyChanged handler for DependencyProperty "SelectedItems"
    /// </summary>
    private static void OnSelectedItemsPropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs args)
    {
        INotifyCollectionChanged collection = args.NewValue as INotifyCollectionChanged;
        if (collection != null)
        {
            // Hook to the Network's SelectedItems
            collection.CollectionChanged += (target as SelectedSyncBehavior).ContextSelectedItems_CollectionChanged;
        }
    }

    /// <summary>
    /// Will be called, when the Network's SelectedItems collection changes
    /// </summary>
    void ContextSelectedItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (_collectionChangedSuspended) return;    // Don't react recursively to CollectionChanged events

        _collectionChangedSuspended = true;

        // Select and unselect items in the grid
        if (e.NewItems != null)
            foreach (object item in e.NewItems)
                AssociatedObject.SelectedItems.Add(item);

        if (e.OldItems != null)
            foreach (object item in e.OldItems)
                AssociatedObject.SelectedItems.Remove(item);

        _collectionChangedSuspended = false;
    }

    /// <summary>
    /// Will be called when the GridView's SelectedItems collection changes
    /// </summary>
    void GridSelectedItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (_collectionChangedSuspended) return;    // Don't react recursively to CollectionChanged events

        _collectionChangedSuspended = true;

        // Select and unselect items in the DataContext
        if (e.NewItems != null)
            foreach (object item in e.NewItems)
                (SelectedItems as IList).Add(item);

        if (e.OldItems != null)
            foreach (object item in e.OldItems)
                (SelectedItems as IList).Remove(item);

        _collectionChangedSuspended = false;
    }

}
//同步RadDataGrid的SelectedItems集合与ViewModel(网络)的SelectedItems集合的行为
//问题是RadDataGrid.SelectedItems是只读集合,因此不能用于双向绑定。
类SelectedSyncBehavior
:行为
{
bool\u collectionChangedSuspended=false;
受保护的覆盖无效附加()
{
base.onatached();
AssociatedObject.SelectedItems.CollectionChanged+=GridSelectedItems\u CollectionChanged;
}
/// 
///DependencyProperty的Getter/Setter,绑定到DataContext的SelectedItems ObservableCollection
/// 
公共InotifyCollection已更改SelectedItems
{
获取{return(INotifyCollectionChanged)GetValue(SelectedItemsProperty);}
set{SetValue(selecteditemsprroperty,value);}
}
/// 
///依赖属性“SelectedItems”是绑定到DataContext的SelectedItems的目标
/// 
公共静态只读从属属性SelectedItemsProperty=
DependencyProperty.Register(“SelectedItems”、typeof(INotifyCollectionChanged)、typeof(SelectedSyncBehavior)、new PropertyMetadata(OnSelectedItemsPropertyChanged));
/// 
///DependencyProperty“SelectedItems”的属性更改处理程序
/// 
SelectedItemsPropertyChanged上的私有静态无效(DependencyObject目标,DependencyPropertyChangedEventArgs参数)
{
INotifyCollectionChanged collection=args.NewValue作为INotifyCollectionChanged;
if(集合!=null)
{
//连接到网络的SelectedItems
collection.CollectionChanged+=(目标为SelectedSyncBehavior)。ContextSelectedItems\u CollectionChanged;
}
}
/// 
///将在网络的SelectedItems集合更改时调用
/// 
void ContextSelectedItems\u CollectionChanged(对象发送者,NotifyCollectionChangedEventArgs e)
{
如果(_collectionChangedSuspended)返回;//不要对CollectionChanged事件进行递归反应
_collectionChangedSuspended=true;
//选择和取消选择网格中的项目
如果(如NewItems!=null)
foreach(e.NewItems中的对象项)
关联对象。选择编辑项。添加(项);
如果(例如,OldItems!=null)
foreach(e.OldItems中的对象项)
关联对象。选择编辑项。删除(项);
_collectionChangedSuspended=false;
}
/// 
///将在GridView的SelectedItems集合更改时调用
/// 
void GridSelectedItems\u CollectionChanged(对象发送方,NotifyCollectionChangedEventArgs e)
{
如果(_collectionChangedSuspended)返回;//不要对CollectionChanged事件进行递归反应
_collectionChangedSuspended=true;
//在DataContext中选择和取消选择项目
如果(如NewItems!=null)
foreach(e.NewItems中的对象项)
(选择编辑项作为IList)。添加(项);
如果(例如,OldItems!=null)
foreach(e.OldItems中的对象项)
(选择编辑项作为IList)。删除(项);
_collectionChangedSuspended=false;
}
}
将此行为用于RadGridView,如下所示:

<i:Interaction.Behaviors>
   <behaviors:SelectedSyncBehavior SelectedItems="{Binding ViewModel.SelectedItems}" />
</i:Interaction.Behaviors>

这里是@Knasterbax类的一个清理副本,带有显式私有修饰符和空传播:

// Behavior for synchronizing Telerik RadDataGrid's SelectedItems collection 
//  with a SelectedItems collection of the ViewModel.   
public class SelectedSyncBehavior : Behavior<RadGridView>
{
    private bool collectionChangedSuspended;
    public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register("SelectedItems",
        typeof(INotifyCollectionChanged), typeof(SelectedSyncBehavior), new PropertyMetadata(OnSelectedItemsPropertyChanged));

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.SelectedItems.CollectionChanged += GridSelectedItems_CollectionChanged;
    }

    public INotifyCollectionChanged SelectedItems
    {
        get { return (INotifyCollectionChanged)GetValue(SelectedItemsProperty); }
        set { SetValue(SelectedItemsProperty, value); }
    }

    private static void OnSelectedItemsPropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs args)
    {
        var collection = args.NewValue as INotifyCollectionChanged;
        if (collection == null) return;
        var selectedSyncBehavior = target as SelectedSyncBehavior;
        if (selectedSyncBehavior != null) collection.CollectionChanged += selectedSyncBehavior.ContextSelectedItems_CollectionChanged;
    }

    private void ContextSelectedItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (collectionChangedSuspended) return;    // Don't react recursively to CollectionChanged events

        collectionChangedSuspended = true;

        if (e.NewItems != null)
            foreach (var item in e.NewItems)
                AssociatedObject.SelectedItems.Add(item);

        if (e.OldItems != null)
            foreach (var item in e.OldItems)
                AssociatedObject.SelectedItems.Remove(item);

        collectionChangedSuspended = false;
    }

    private void GridSelectedItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (collectionChangedSuspended) return;    // Don't react recursively to CollectionChanged events

        collectionChangedSuspended = true;

        if (e.NewItems != null)
            foreach (var item in e.NewItems)
            {
                var list = SelectedItems as IList;
                list?.Add(item);
            }

        if (e.OldItems != null)
            foreach (var item in e.OldItems)
            {
                var list = SelectedItems as IList;
                list?.Remove(item);
            }

        collectionChangedSuspended = false;
    }

}
//同步Telerik RadDataGrid的SelectedItems集合的行为
//使用ViewModel的SelectedItems集合。
公共类SelectedSyncBehavior:行为
{
私人收藏变更暂停;
公共静态只读DependencyProperty SelectedItemsProperty=DependencyProperty.Register(“SelectedItems”,
typeof(INotifyCollectionChanged)、typeof(SelectedSyncBehavior)、new PropertyMetadata(OnSelectedItemsPropertyChanged));
受保护的覆盖无效附加()
{
base.onatached();
AssociatedObject.SelectedItems.CollectionChanged+=GridSelectedItems\u CollectionChanged;
}
公共InotifyCollection已更改SelectedItems
{
获取{return(INotifyCollectionChanged)GetValue(SelectedItemsProperty);}
set{SetValue(selecteditemsprroperty,value);}
}
SelectedItemsPropertyChanged上的私有静态无效(DependencyObject目标,DependencyPropertyChangedEventArgs参数)
{
var collection=args.NewValue作为INo
public class SelectedItemsBehavior : Behavior<RadGridView>
{
    private bool collectionChangedSuspended;

    /// <summary>
    /// Called after the behavior is attached to an AssociatedObject.
    /// </summary>
    /// <remarks>
    /// Override this to hook up functionality to the AssociatedObject.
    /// </remarks>
    protected override void OnAttached()
    {
        base.OnAttached();
        this.AssociatedObject.SelectedItems.CollectionChanged += this.GridSelectedItemsCollectionChanged;
    }

    /// <summary>
    /// Getter/Setter for DependencyProperty, bound to the DataContext's SelectedItems ObservableCollection
    /// </summary>
    public INotifyCollectionChanged SelectedItems
    {
        get => (INotifyCollectionChanged)this.GetValue(SelectedItemsProperty);
        set => this.SetValue(SelectedItemsProperty, value);
    }

    /// <summary>
    /// Dependency Property "SelectedItems" is target of binding to DataContext's SelectedItems
    /// </summary>
    public static readonly DependencyProperty SelectedItemsProperty =
        DependencyProperty.Register("SelectedItems", typeof(INotifyCollectionChanged), typeof(SelectedItemsBehavior), new PropertyMetadata(OnSelectedItemsPropertyChanged));

    /// <summary>
    /// PropertyChanged handler for DependencyProperty "SelectedItems"
    /// </summary>
    private static void OnSelectedItemsPropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs args)
    {
        INotifyCollectionChanged collection = args.NewValue as INotifyCollectionChanged;
        if (collection != null)
        {
            collection.CollectionChanged += ((SelectedItemsBehavior)target).ContextSelectedItemsCollectionChanged;
        }
    }

    /// <summary>
    /// Will be called, when the Network's SelectedItems collection changes
    /// </summary>
    private void ContextSelectedItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (this.collectionChangedSuspended)
        {
            return; 
        }

        this.collectionChangedSuspended = true;

        if (e.NewItems != null)
        {
            foreach (object item in e.NewItems)
            {
                this.AssociatedObject.SelectedItems.Add(item);
            }
        }

        if (e.OldItems != null)
        {
            foreach (object item in e.OldItems)
            {
                this.AssociatedObject.SelectedItems.Remove(item);
            }
        }

        this.collectionChangedSuspended = false;
    }

    /// <summary>
    /// Will be called when the GridView's SelectedItems collection changes
    /// </summary>
    private void GridSelectedItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (this.collectionChangedSuspended)
        {
            return;
        }

        this.collectionChangedSuspended = true;

        if (e.NewItems != null)
        {
            foreach (object item in e.NewItems)
            {
                ((IList)this.SelectedItems).Add(item);
            }
        }

        if (e.OldItems != null)
        {
            foreach (object item in e.OldItems)
            {
                ((IList)this.SelectedItems).Remove(item);
            }
        }

        this.collectionChangedSuspended = false;
    }
}