将WPF DataGrid文本列的前景绑定

9

我尝试构建一个DataGrid,并且想要将其中一个TextColumn的Foreground属性绑定到一个日期上,这样如果该日期在过去,它就会变成红色。

以下是XAML代码:

<toolkit:DataGridTextColumn 
   Binding="{Binding Path=Prüfdatum, Converter={StaticResource TimestampToDateConverter}}"
   Header="Prüfdatum" 
   Foreground="{Binding Path=Prüfdatum, Converter={StaticResource TimestampToColorConverter},
   ConverterParameter=Prüfdatum}" />

这是我的转换器:

    class TimestampToColorConverter: IValueConverter
{
    #region IValueConverter Member

    public object Convert(object value, Type targetType, 
           object parameter, System.Globalization.CultureInfo culture)
    {
        string Datum = value.ToString();
        int year = System.Convert.ToInt32(Datum.Substring(6, 4));
        int month = System.Convert.ToInt32(Datum.Substring(3, 2));
        int day = System.Convert.ToInt32(Datum.Substring(0, 2));
        int hour = System.Convert.ToInt32(Datum.Substring(11, 2));
        int minute = System.Convert.ToInt32(Datum.Substring(14, 2));
        int second = System.Convert.ToInt32(Datum.Substring(17, 2));
        DateTime Time = new DateTime(year, month, day, hour, minute, second);
        if (Time < System.DateTime.Now)
        {
            return Brushes.Red as Brush;
        }
        else
        {
            return Brushes.Black as Brush;
        }

    }

    public object ConvertBack(object value, Type targetType, 
         object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }

    #endregion
}

我不知道出了什么问题,但转换器甚至没有被调用(第一个转换器完美运行)。输出窗口显示如下:

System.Windows.Data Error: 2 : 找不到控制 FrameworkElement 或 FrameworkContentElement 以便为目标元素进行绑定。 BindingExpression:Path=Prüfdatum; DataItem=null; 目标元素为
'DataGridTextColumn' (HashCode=16187528); 目标属性为 'Foreground'(类型为 'Brush')

希望你们能帮我解决这个问题。
谢谢。
3个回答

10

DataGridTextColumn告诉DataGrid在该列的每一行中创建一个TextBlock。 DataGridTextColumn.Binding然后设置TextBlock.Text的绑定,每次创建新行和该行的新TextBlock时都会触发。

我不知道绑定是否被执行过,但最多只执行一次(即不是每一行都执行):

Binding ="{Binding Path=Prüfdatum,Converter = {StaticResource TimestampToDateConverter}}"

正确的解决方案是为该textblock创建一个样式,并为ForeGround定义绑定。这将针对生成的每个TextBlock执行。挑战在于TextBlock如何找到数据。可以通过相对于DataGridRow的绑定来实现这一点,DataGridRow是视觉树中的祖先。 DataGridRow.Item可以访问网格后面的数据:

<Window.Resources>
  <Style x:Key="ForegroundStyle" TargetType="TextBlock">
    <Setter Property="Foreground" 
      Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}, 
      Path=Item.Prüfdatum, 
      Converter={StaticResource TimestampToColorConverter}/>
  </Style>
</Window.Resources>

<DataGrid>
  <DataGrid.Columns>
    <DataGridTextColumn Binding="{Binding SomeData}" ElementStyle="{StaticResource ForegroundStyle}"/>
</DataGrid.Columns>

很复杂吧?我建议您阅读我详细的关于datagrid格式化的文章: http://www.codeproject.com/Articles/683429/Guide-to-WPF-DataGrid-formatting-using-bindings?msg=5037235#xx5037235xx

祝您好运,您需要它 :-)


4
数据网格文本列的前景属性数据绑定无法正常工作。
Peter Huber的回答是一个很好的解决方案。这里有一个稍微简单一些的替代方法。
<DataGridTemplateColumn Header="Heading">
    <DataGridTemplateColumn.CellTemplate >
        <DataTemplate>
            <TextBlock Text="{Binding SomeData}" 
                Foreground="{Binding SomeData, Converter={StaticResource TimestampToColorConverter}}" />
       </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

0

由于您已经绑定到DataGrid,因此在DataGridTextColumn中不需要使用“Binding”,并且也不需要使用ConverterParameter,因为您的转换器没有使用该参数。请尝试以下操作

<toolkit:DataGridTextColumn  Header="Prüfdatum" Foreground="{Binding Path=Prüfdatum, Converter={StaticResource TimestampToColorConverter}}" />

但我也希望“Prüfdatum”作为内容(参数我同意,这只是一个测试)。 - Tokk
你能在转换器中设置一个断点,看看是否得到了值吗? - Ragunathan
这就是我发现转换器在运行时没有被调用的方式 - Tokk
可以提供一下代码,您是如何为该控件或DataGrid绑定DataContext的? - Ragunathan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接