2

I'm using Xceed DataGridControl in selection mode set to "Extended" (multi selection).

I'm using MVVM. Each row is bound to an instance of my class MyRowObject. MyRowObject has a boolean property "IsSelected". I want to bind a DataGridControl row "IsSelected" property (if any, I can't find one that is read/write) to my MyRowObject.IsSelected.

Does anyone know if it is possible to do it with Xceed DataGridControl and how to do it? If there is no direct binding possible, does anyone has written a behavior for this?

Eric Ouellet
  • 10,996
  • 11
  • 84
  • 119
  • Please check this post helps you http://stackoverflow.com/questions/1631543/how-do-i-detect-row-selection-in-the-xceed-datagrid-for-wpf – user1386121 Apr 21 '16 at 15:20
  • Thanks, The link is about single selection. it works fine for single selection. The problem I have is about multi selection for which you should bind per row and IsSelected could only be read, there is no setter for that property (that I know). – Eric Ouellet Apr 21 '16 at 15:39

1 Answers1

2

Actually this is not possible to do that directly. That is true for any version up to now (2016-04-25).

But Xceed was kind enough to give me the code to accomplish the same behavior (see below). I slightly modified their code in order to put it bi-directional and prevent an Exception but otherwise the behavior is exactly what I was looking for. Please note that it is hard coded to the property "IsSelected".

Instead of using: DataGridControl, use: 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;
        }
    }
}
Eric Ouellet
  • 10,996
  • 11
  • 84
  • 119