c# - Xceed DataGrid 设置为行 :MultiSelect - How to bind selected row to its MVVM row data

标签 c# wpf mvvm datagrid xceed

我在设置为“扩展”(多重选择)的选择模式下使用 Xceed DataGridControl。

我正在使用 MVVM。每行都绑定(bind)到我的类 MyRowObject 的一个实例。 MyRowObject 有一个 bool 属性“IsSelected”。我想将 DataGridControl 行“IsSelected”属性(如果有,我找不到可读/写的属性)绑定(bind)到 MyRowObject.IsSelected。

有谁知道是否可以使用 Xceed DataGridControl 来做到这一点以及如何做到这一点?如果无法直接绑定(bind),是否有人为此编写了行为?

最佳答案

实际上这是不可能直接做到的。对于迄今为止的任何版本(2016-04-25)都是如此。

但是 Xceed 很友善地给了我完成相同行为的代码(见下文)。我稍微修改了他们的代码,以便将其设置为双向并防止异常,但除此之外,该行为正是我所寻找的。请注意,它被硬编码到属性“IsSelected”。

不要使用:DataGridControl,而是使用:DataGridControlCustom。

using System;
using System.ComponentModel;
using System.Reflection;
using System.Windows;
using Xceed.Wpf.DataGrid;

namespace XceedUtil
{
    public class DataGridControlCustom : DataGridControl
    {
        public DataGridControlCustom()
        {
            SelectionChanged += OnSelectionChanged;
        }

        private void OnSelectionChanged(object sender, DataGridSelectionChangedEventArgs e)
        {
            foreach (SelectionInfo selectionInfo in e.SelectionInfos)
            {
                foreach (var item in selectionInfo.AddedItems)
                {
                    PropertyInfo pi = item.GetType().GetProperty("IsSelected", BindingFlags.Public | BindingFlags.Instance);
                    if (pi != null && pi.CanWrite)
                    {
                        pi.SetValue(item, true);
                    }
                }
                foreach (var item in selectionInfo.RemovedItems)
                {
                    PropertyInfo pi = item.GetType().GetProperty("IsSelected", BindingFlags.Public | BindingFlags.Instance);
                    if (pi != null && pi.CanWrite)
                    {
                        pi.SetValue(item, false);
                    }
                }
            }
        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            return new CustomDataRow();
        }
    }

    public class CustomDataRow : DataRow, IWeakEventListener
    {
        protected override void PrepareContainer(DataGridContext dataGridContext, object item)
        {
            base.PrepareContainer(dataGridContext, item);

            PropertyInfo pi = item.GetType().GetProperty("IsSelected", BindingFlags.Public | BindingFlags.Instance);
            if (pi != null && pi.CanWrite)
            {
                if ((bool)pi.GetValue(item) == true)
                {
                    dataGridContext.SelectedItems.Add(item);
                }
            }

            PropertyChangedEventManager.AddListener(item as INotifyPropertyChanged, this, "IsSelected");
        }

        private void UpdateSelectedItems(object item)
        {
            var selectedItems = DataGridControl.GetDataGridContext(this).SelectedItems;
            try
            {
                PropertyInfo pi = item.GetType().GetProperty("IsSelected", BindingFlags.Public | BindingFlags.Instance);
                if (pi != null && pi.CanWrite)
                {
                    if ((bool) pi.GetValue(item) == true)
                    {
                        selectedItems.Add(item);
                    }
                    else
                    {
                        selectedItems.Remove(item);
                    }
                }
            }
            catch (InvalidOperationException ex)
            {

            }
        }

        protected override void ClearContainer()
        {
            var item = this.DataContext;
            PropertyChangedEventManager.RemoveListener(item as INotifyPropertyChanged, this, "IsSelected");

            var selectedItems = DataGridControl.GetDataGridContext(this).SelectedItems.Remove(item);

            base.ClearContainer();
        }

        bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
        {
            if (managerType == typeof(PropertyChangedEventManager))
            {
                this.UpdateSelectedItems(sender);
            }

            return true;
        }
    }
}

关于c# - Xceed DataGrid 设置为行 :MultiSelect - How to bind selected row to its MVVM row data,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36771966/

相关文章:

c# - 异步服务器套接字的适当积压是什么?

c# - 如何知道类型参数是否是动态的?

WPF MVVM 获取文本框数据到 ViewModel

xaml - ResourceLoader 在 ViewModel 中返​​回错误的语言

c# - 单选按钮作为一组在不同的面板中

c# - Windows 服务不执行代码

wpf - XAML IsMouseOver 和 IsEnabled 的奇怪冲突导致按钮在禁用时显示为事件状态

c# - 如何清除通过行为绑定(bind)到 ViewModel 的 WPF PasswordBox?

wpf - 无法清除对ListView的选择

c# - 将 WPF ComboBox 绑定(bind)到自定义列表