WPF DataGrid的结构 – 根据值更改单元格

我确实将Object绑定到DataGridTextColumn并希望从相应的CellStyle中引用其中一个属性。 我假设此列的每个单元格都包含一个MyObject实例。 但是我无法在DataGridCell找到对Object的引用(我使用了一个简单的转换器来设置断点并搜索了DataGridCell -object很长一段时间)。

我正在寻找属性MyObject.IsEnabled,并希望在路径属性中引用??? 在下面的代码中。 有什么建议?

            

编辑:

由于我希望稍后将此样式应用于我的DataGrid的所有单元格,因此必须通过RelativeSource查找绑定到单元格的对象,而不是向MyObject添加硬编码绑定。

由于antiocol的输入,我能够为我的案例找到一个可能适用于类似问题的解决方案。

由于问题是我们无法从CellStyle访问Cell或CellModelCellStyle ,因此我们使用DataGridCell上的附加Property将整个CellModel存储在那里。 从那里我们可以将DataGridCell任何可访问属性绑定到我们的CellModel任何属性。

附属物的代码:

 public static class DataGridUtils { public static CellModel GetCellModel(DependencyObject obj) { return (CellModel)obj.GetValue(CellModelProperty); } public static void SetCellModel(DependencyObject obj, CellModel value) { obj.SetValue(CellModelProperty, value); } public static readonly DependencyProperty CellModelProperty = DependencyProperty.RegisterAttached("CellModel", typeof(CellModel), typeof(DataGridUtils), new UIPropertyMetadata(null)); 

我们需要在DataGrid中的每个单元格上设置此属性。 我没有在XAML中找到一个很好的解决方案,所以现在我在检索信息之前将它设置在转换器中。 (有待改进的建议)

转换器:

 public class CellToEnabledConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { var cell = values[0] as DataGridCell; DataGridTextColumn column = cell.Column as DataGridTextColumn; //you should probably check if column is null after casting. Binding b = column.Binding as Binding; //Any suggestions on how to create a Binding to the parent object properly? //I needed this workaround since I bind `MyObject.Value` to the `DataGridTextColumn`, //but need a reference to `MyObject` here. Binding b1 = new Binding(b.Path.Path.Split('.')[0]){ Source = cell.DataContext }; cell.SetBinding(DataGridUtils.CellModelProperty, b1); CellModel c = DataGridUtils.GetCellModel(cell); return c.IsEnabled; } 

现在我们可以在XAML中定义全局Style并将其应用于整个DataGrid而不是单个列。

                    

由于我在网上发现了几条评论,称“使用当前的DataGrid无法根据其值设置单元格”,我希望这种解决方法可以帮助某人。

我一直在为你的问题尝试另一种解决方案。

        

另一方面,我假设您的DataGridItemsSourceElement对象的集合(当然还是类似的东西)

 public class Element { public string Name { get; set; } public MyObject MyObject1 { get; set; } public MyObject MyObject2 { get; set; } } public class MyObject { public string Name { get; set; } public bool IsEnabled { get; set; } public override string ToString() { return Name; } } 

最后,转换器:

 public class DataGridCellToBooleanConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { string propertyToAppend = parameter as string; var cell = value as DataGridCell; var column = cell.Column as DataGridTextColumn; Binding b = column.Binding as Binding; Binding b1 = new Binding(string.Join(".", b.Path.Path, propertyToAppend)) { Source = cell.DataContext }; CheckBox dummy = new CheckBox(); dummy.SetBinding(CheckBox.IsCheckedProperty, b1); return dummy.IsChecked; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } 

棘手的部分是使用ConverterParameter来传递要在DataTrigger绑定的属性的名称。

PS你可以使用reflection而不是hacky CheckBox dummy元素,但这对我有用。

希望这可以帮助

我唯一能想到的是将每个DataGridTextColumn切换到DataGridTemplateColumn并在每个CellTemplate内部添加一些ContentControl,其DataContext绑定到该列中的属性。

这样你就可以为ContentControl创建一个可重用的Style,因为DataGridCell对你没有任何帮助:P

         

你必须首先修复DataTrigger的sintax,如下所示:

      

注意DataTrigger的Binding属性。 在您必须编写Path属性中,在您的情况下IsEnabled由于每个DataGridCell中的DataContext将是MyObject对象的实例。 您不需要使用RelativeSource因为您的Binding指向MyObject ,如前所述。

如果要将此样式创建为资源,可以执行以下操作: