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

dna*_*a86 3 selecteditem telerik mvvm radgridview caliburn.micro

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

Kna*_*bax 11

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;
    }

}
Run Code Online (Sandbox Code Playgroud)

像RadGridViews一样使用此行为,如下所示:

<i:Interaction.Behaviors>
   <behaviors:SelectedSyncBehavior SelectedItems="{Binding ViewModel.SelectedItems}" />
</i:Interaction.Behaviors>
Run Code Online (Sandbox Code Playgroud)

  • 这应该是选定的答案!telerik博客似乎都缺乏这里找到的完整解决方案. (3认同)
  • 不要忘记实例化 SelectedItems 属性绑定到的集合,浪费了 15 分钟... (2认同)