DataGrid SelectionUnit=Cell отключает всю поддержку выбранного ряда?

.Net 4 WPF DataGrid C# MMVM

Когда DataGrid SelectionUnit является полным рядом, wpf databinding и collectionview заботятся о том, чтобы дать мне знать в модели представления, что является активно выбранным элементом через свойство currentitem представления. Это отлично работает для сетки с доступом только для чтения, где режим выбора установлен на fullrow.

Теперь у меня есть редактируемая сетка. Я установил SelectionUnit=Cell, чтобы было легче определить, в какой ячейке находится элемент. Теперь внезапно сетка больше не имеет возможности отслеживать элемент выделения. Я даже не могу установить SelectedItem, когда установлен режим ячейки. Так что теперь вью-модель всегда думает, что она находится в первом ряду. Я могу обработать SelectedCellsChanged в гриде, чтобы выяснить, в каком ряду я нахожусь, у меня просто нет способа сообщить об этом вью-модели, поскольку SelectedItem грида больше не может быть установлен!

Я не понимаю, почему сетка не может иметь SelectedItem в режиме выбора ячеек.

Кроме жесткого кодирования в моем гриде для приведения ItemSource к моему collectionview для вызова MoveCurrentTo из события SelectedCellsChanged, есть ли какой-либо другой MVVM истинный способ сохранить CurrentItem представления синхронизированным с гридом?

Либо это, либо я изменю стиль грида, чтобы удалить или уменьшить эффект выделения строки, когда у меня есть редактируемый грид.

11
задан H.B. 28 February 2012 в 21:25
поделиться

1 ответ

Я нашел отличное решение для этого на MSDN с помощью присоединенных свойств:

<DataGrid ItemsSource="{Binding}" IsReadOnly="True" SelectionUnit="Cell">
  <DataGrid.CellStyle>
    <Style TargetType="{x:Type DataGridCell}">
      <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
          <Setter Property="local:DataGridAttachedProperties.IsCellSelected" Value="True"/>
        </Trigger>
        <Trigger Property="IsSelected" Value="False">
          <Setter Property="local:DataGridAttachedProperties.IsCellSelected" Value="False"/>
        </Trigger>
      </Style.Triggers>
    </Style>
  </DataGrid.CellStyle>
  <DataGrid.ItemContainerStyle>
    <Style TargetType="{x:Type DataGridRow}">
      <Style.Triggers>
        <Trigger Property="local:DataGridAttachedProperties.IsCellSelected" Value="True">
          <Setter Property="BorderThickness" Value="2"/>
          <Setter Property="BorderBrush" Value="Red"/>
          <Setter Property="Background" Value="Yellow"/>
          <Setter Property="Opacity" Value="0.7"/>
        </Trigger>
      </Style.Triggers>
    </Style>
  </DataGrid.ItemContainerStyle>
</DataGrid>

И C#:

public class DataGridAttachedProperties
{
    public static bool GetIsCellSelected(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsCellSelectedProperty);
    }
    public static void SetIsCellSelected(DependencyObject obj, bool value)
    {
        obj.SetValue(IsCellSelectedProperty, value);
    }
    public static readonly DependencyProperty IsCellSelectedProperty =
        DependencyProperty.RegisterAttached("IsCellSelected", typeof(bool), typeof(DataGridAttachedProperties), new UIPropertyMetadata(false,
        (o, e) =>
        {
            if (o is DataGridCell)
            {
                DataGridRow row = VisualTreeHelperEx.FindVisualParent<DataGridRow>(o as DataGridCell);
                row.SetValue(DataGridAttachedProperties.IsCellSelectedProperty, e.NewValue);
            }
        }));
}
public class VisualTreeHelperEx
{
    public static T FindVisualParent<T>(DependencyObject child)
    where T : DependencyObject
    {
        DependencyObject parentObject = VisualTreeHelper.GetParent(child);
        if (parentObject == null) return null;
        T parent = parentObject as T;
        if (parent != null)
        {
            return parent;
        }
        else
        {
            return FindVisualParent<T>(parentObject);
        }
    }
}
0
ответ дан 3 December 2019 в 11:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: