Привязка свойства клеточного объекта для DataGridCell в DataGrid WPF
-
26-09-2019 - |
Вопрос
Используя DataGrid WPF, у меня необходимо изменить различные дисплеи и связанные свойства DataGridCell - такого как передний план, fontStyle, изношенный и т. Д. На основе соответствующего значения свойства объекта клеток.
Теперь это легко сделать в коде, например (используя наблюдаемую коллекцию наблюдающих средств):
var b = new Binding("IsLocked") { Source = row[column], Converter = new BoolToFontStyleConverter() };
cell.SetBinding(Control.FontStyleProperty, b);
и работает нормально, однако я не вижу, как это сделать в XAML, так как я не могу найти способ установить Дорожка к собственности клеточного объекта.
Одна попытка XAML:
<Setter Property="FontStyle">
<Setter.Value>
<MultiBinding Converter="{StaticResource IsLockedToFontStyleConverter}" Mode="OneWay" UpdateSourceTrigger="PropertyChanged">
<Binding />
<Binding RelativeSource="{x:Static RelativeSource.Self}"/>
</MultiBinding>
</Setter.Value>
</Setter>
Но не связано с Заблокирован свойство
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var row = (RowViewModel) values[0];
var cell = (DataGridCell) values[1];
if (cell != null && row != null)
{
var column = DataGridMethods.GetColumn(cell);
return row[column].IsLocked ? "Italic" : "Normal";
}
return DependencyProperty.UnsetValue;
}
Обратите внимание, что предыдущая версия вернулась Row [Col] .islocked и установить FontStyle с помощью DataTatrigger, но возвращенный объект не является входом в падкет.
Обратите внимание, что, конечно, что приложение не знает, что столбец в разработке времени.
Наконец, DataTable наступает слишком неэффективным для моих требований, но мне было бы интересно посмотреть, как это делается с деформаторами в любом случае, если для них такое решение, это может быть полезно в другом месте (хотя я предпочитаю использовать коллекции).
Конечно, это обычная проблема, и я WPF Noobie пытается пойти все MVVM на моем проекте, но этот вопрос удерживает меня обратно в отношении использования DataGrid WPF.
Решение
Ну вот самое простое решение, которое я нашел. (На самом деле у меня было это до того, как я опубликовал этот и другой вопрос, но был смущен в таком решении. Также ничего не слышала здесь, и просто на всякий случай, если кто-то другой столкнулся с той же проблемой, я думал, что буду поделиться этим.)
Поместите ссылку на объект ячейки в свойстве Tag Tag Tag Tag. Я делаю это с комбинацией XAML и привязки кода внутри преобразователя следующим образом:
<Setter Property="Tag">
<Setter.Value>
<MultiBinding Converter="{StaticResource CellViewModelToTagConverter}" Mode="OneWay" UpdateSourceTrigger="PropertyChanged">
<Binding />
<Binding RelativeSource="{x:Static RelativeSource.Self}"/>
</MultiBinding>
</Setter.Value>
</Setter>
и
public class CellViewModelToTagConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var row = values[0] as RowViewModel;
var cell = values[1] as DataGridCell;
if (row != null && cell != null)
{
var column = DataGridMethods.GetColumn(cell);
// hack within hack!!! (using tag way is itself a hack?)
var b = new Binding("Self") {Source = row[column]};
cell.SetBinding(FrameworkElement.TagProperty, b);
//...
//return row[column];
return DependencyProperty.UnsetValue;
}
return DependencyProperty.UnsetValue;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
Вы можете сказать, что я думаю об этом решении моими комментариями внутри преобразователя. (Мне пришлось добавить себе свойство к элементу клеток и сделать себя = это в конструкторе).
Тем не менее, это позволяет кодировать мою детаград, чтобы быть полностью MVVM - если вы принимаете то, что я сделал внутри преобразователя, соответствует MVVM. Во всяком случае, это работает!
Так что делаю так, как я могу видеть и управлять всем от XAML, таких как управление такими связывающими только на определенных столбцах, поместив XAML в соответствующих колоннах Cellstyles (это не делает это через DataGrid.CellStyle).
В любом случае, пример использования
<Style.Triggers>
<DataTrigger Value="true" Binding="{Binding RelativeSource={RelativeSource Self}, Path=Tag.IsLocked}">
<Setter Property="FontStyle" Value="Italic"/>
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
На уровне XAML простым, так и IMHO элегантный (особенно для различных всплывающих подсказок и всплывающих окон, для которых я делаю тяжелое использование свойств клеточного объекта). Однако я уверен, что есть лучший способ сделать это, есть ли там?
Надеюсь, это все уходит, когда я могу использовать Net 4.0 и динамические объекты, но для этого проекта я не могу.