.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 представления синхронизированным с гридом?
Либо это, либо я изменю стиль грида, чтобы удалить или уменьшить эффект выделения строки, когда у меня есть редактируемый грид.
Я нашел отличное решение для этого на 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);
}
}
}