将单元格对象的属性绑定到 WPF DataGrid 中的 DataGridCell [英] Binding a cell object's property to a DataGridCell in WPF DataGrid

查看:21
本文介绍了将单元格对象的属性绑定到 WPF DataGrid 中的 DataGridCell的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 WPF DataGrid 我需要根据单元格对象属性的相关值更改 DataGridCell 的各种显示和相关属性 - 例如 Foreground、FontStyle、IsEnabled 等.

Using the WPF DataGrid I have the need to change various display and related properties of a DataGridCell - such as Foreground, FontStyle, IsEnabled and so on - based on the relevant value of the cell object property.

现在这很容易在代码中实现,例如(使用 ObservableDictionaries 的 Observable 集合):

Now this is easy to do in code, for example (using an Observable Collection of ObservableDictionaries):

  var b = new Binding("IsLocked") { Source = row[column], Converter = new BoolToFontStyleConverter() };
  cell.SetBinding(Control.FontStyleProperty, b);

并且工作正常,但是我看不到如何在 XAML 中执行此操作,因为我找不到将 Path 设置为单元格对象的属性的方法.

and works fine, however I cannot see how to do this in XAML since I can find no way to set Path to a cell object's property.

一次 XAML 尝试是:

One XAML attempts is:

<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 属性

but there is no binding to the IsLocked property

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 并使用 DataTrigger 设置了 FontStyle,但返回的对象不是数据绑定的.

Please note that a previous version returned row[col].IsLocked and set the FontStyle using a DataTrigger but a returned object is not databound.

当然,请注意,应用程序在设计时并不知道列是什么.

Note, of course, that the application does not know what the columns are at design time.

最后,DataTable 的效率对于我的要求来说太低了,但我很想看看这是如何用 DataTables 完成的,如果有这样的解决方案,这可能在其他地方很有用(尽管我更喜欢使用集合).

Finally DataTable's are far too inefficient for my requirements but I would be interested to see how this is done with DataTables anyway, if there is such a solution for them, this might be useful elsewhere (although I prefer using collections).

这当然是一个常见问题,我是一个 WPF noobie,试图在我的项目中使用所有 MVVM,但是这个问题阻碍了我使用 WPF DataGrid.

Surely this is a common issue and I am a WPF noobie trying to go all MVVM on my project, but this issue is holding me back with respect to using the WPF DataGrid.

推荐答案

这是我找到的最简单的解决方案.(实际上我在发布这个和另一个问题之前就已经有了它,但对这样的解决方案感到尴尬.因为在这里没有听到其他任何消息,以防万一其他人面临同样的问题,我想我会分享它.)

Well here is the simplest solution I have found. (Actually I had it before I posted this and the other question but was embarrased at such a solution.Since have heard nothing else here and just it is in case anyone else is faced with the same problem, I thought I would share it.)

在 DataGridCell Tag 属性中放置对单元格对象的引用.我使用 XAML 和转换器内的代码绑定的组合来执行此操作,如下所示:

Put a reference to the cell object in the DataGridCell Tag property. I do this with a combination of XAML and a code binding inside a converter as follows:

   <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 对象添加一个 Self 属性,并在构造函数中设置 Self=this).

You can tell what I think of this solution by my comments inside the converter.(I had to add a Self property to the Cell object and make Self=this in the constructor).

它仍然使我的 Datagrid 编码完全是 MVVM - 如果您接受我在转换器中所做的与 MVVM 一致.无论如何它都有效!

Still it enables my Datagrid coding to be entirely MVVM - if you accept that what I have done inside the converter is consistent with MVVM. Anyway it works!

因此,通过这种方式,我可以查看和管理来自 XAML 的所有内容,例如通过将 XAML 放置在相关列的单元格样式中(不是通过 DataGrid.CellStyle 执行此操作)来仅在某些列上控制此类绑定.

So doing it this way I can see and manage everything from XAML such as control such binding only on certain columns by placing the XAML within the relevant column cellstyles (that is not doing this via DataGrid.CellStyle).

无论如何,用法的一个例子是

Anyway, an example of usage is

<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 级别,它既简单又优雅(尤其是对于我大量使用单元格对象属性的各种工具提示和弹出窗口).但是我确信有更好的方法来做到这一点,是吗?

On the XAML level it is both simple and IMHO elegant (especially for various ToolTips and Popups for which I make heavy usage of cell object's properties). However I am sure there is a better way of doing this, is there?

希望当我可以使用 Net 4.0 和动态对象时,这一切都会消失,但对于这个项目,我不能.

Hopefully this all goes away when I can use Net 4.0 and dynamic objects, but for this project I cannot.

这篇关于将单元格对象的属性绑定到 WPF DataGrid 中的 DataGridCell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆