Xceed DataGrid настроен на строку: MultiSelect — как связать выбранную строку с данными строки MVVM

Я использую Xceed DataGridControl в режиме выбора, установленном на «Расширенный» (множественный выбор).

Я использую МВВМ. Каждая строка привязана к экземпляру моего класса MyRowObject. MyRowObject имеет логическое свойство IsSelected. Я хочу привязать свойство строки DataGridControl "IsSelected" (если есть, я не могу найти тот, который доступен для чтения/записи) к моему MyRowObject.IsSelected.

Кто-нибудь знает, можно ли это сделать с помощью Xceed DataGridControl и как это сделать? Если прямая привязка невозможна, написал ли кто-нибудь поведение для этого?


person Eric Ouellet    schedule 21.04.2016    source источник
comment
Пожалуйста, проверьте, что этот пост поможет вам stackoverflow.com/questions/1631543/   -  person user1386121    schedule 21.04.2016
comment
Спасибо, ссылка посвящена одиночному выбору. он отлично работает для одиночного выбора. Проблема, с которой я столкнулся, связана с множественным выбором, для которого вы должны привязываться к каждой строке, а IsSelected можно только читать, для этого свойства нет установщика (что я знаю).   -  person Eric Ouellet    schedule 21.04.2016


Ответы (1)


На самом деле это невозможно сделать напрямую. Это верно для любой версии до сих пор (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;
        }
    }
}
person Eric Ouellet    schedule 25.04.2016
comment
мы собираемся реализовать это, вы видели какие-либо проблемы с этим подходом? - person phabtar; 23.08.2018