结合细胞对象的属性在WPF数据网格中的DataGridCell
-
26-09-2019 - |
题
使用WPF数据网格我有需要改变各种显示和DataGridCell的相关属性 - 如前景,FontStyle,的IsEnabled等等 - 基于所述小区对象属性的相关值。
现在这是很容易在代码来执行,例如(使用ObservableDictionaries的观察集合):
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>
但没有结合到 IsLocked 属性
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;
}
请注意,前一个版本返回行[COL] .IsLocked 并设置使用DataTrigger但返回的对象不是数据绑定的fontStyle。
请注意,当然,应用不知道列是在设计时是什么。
最后DataTable的是迄今为止我的要求太低效,但我很想看到它是如何与数据表反正做,如果有他们这样的解决方案,这可能是有用的其他地方(虽然我更喜欢使用集合)。
当然,这是一个常见的问题,我是一个WPF noobie试图去对我的项目的所有MVVM,但这个问题拖我对于使用WPF的DataGrid。
解决方案
那么这里是我已经找到了简单的解决方案。 (其实我是有我张贴在此之前,另一问题,但在这样一个solution.Since是让人看见听见没有别的这里只是它的情况下,任何人都面临着同样的问题,我想我会分享。)
把在DataGridCell 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();
}
}
您可以告诉我怎么想的这个解决方案由我的意见转换器内的。(我有一个自我属性添加到Cell对象,使自我在构造函数=这一点)。
不过它使我的数据网格编码是完全MVVM - 如果你接受我所转换器内部完成与MVVM一致。反正它的工作原理!
所以做这种方式我可以看到和诸如控制例如通过将XAML相关列cellstyles(即不经由DataGrid.CellStyle这样做)内的某些列仅结合从XAML管理一切。
总之,使用的一个例子是
<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和动态对象,但对于这个项目,我做不到。