【问题标题】:WPF: passing datagridrow object to converterWPF:将datagridrow对象传递给转换器
【发布时间】:2015-12-18 11:44:04
【问题描述】:

我在 WPF 中将对象传递给转换器时遇到问题。

我的 DataGrid 看起来像:

<DataGrid x:Name="customTasksDataGrid" Margin="10,10,10,38" Grid.Column="1" IsReadOnly="True" AutoGenerateColumns="False">
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Setter Property="ToolTip">
                <Setter.Value>
                    <TextBlock Text="{Binding Path=., Converter={StaticResource converter}, NotifyOnTargetUpdated=True}"/>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.RowStyle>
    <DataGrid.Columns>
        <DataGridTextColumn Header="ID" Binding="{Binding ID}"/>
        <DataGridTextColumn Header="Klient" Binding="{Binding Client.Names}"/>
        ...
    </DataGrid.Columns>
</DataGrid>

转换器:

public class DateToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        CustomTask t = (CustomTask)value;
        Console.WriteLine(t.ToString()); // HERE
        ...
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

运行我的 prog 标记行时抛出错误,我的 CustomTask t 对象为空。我做错了什么?

编辑:

按照 Vadim Martynov 的建议,我将转换器更改为:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    if (value == null)
        return null;
    CustomTask t = (CustomTask)value;
    ...
}

现在完美运行!谢谢

【问题讨论】:

  • 如果你调用转换器会发生什么,即替换为: 客户端名称是否显示在工具提示中?
  • @Stew52 no 在这种情况下转换器从不调用
  • 它不会这样做,因为您已将其删除。但它是否显示了您的期望?即工具提示的数据上下文是您期望的吗?

标签: c# .net wpf datagrid ivalueconverter


【解决方案1】:

下一个代码对我来说很好用:

<DataGrid.RowStyle>
    <Style TargetType="DataGridRow">
        <Setter Property="ToolTipService.ToolTip" Value="{Binding Path=., Converter={StaticResource converter}}" />
    </Style>
</DataGrid.RowStyle>

我还注意到,您的代码中只有一个具有空值的调用。下一次调用(如果您的绑定没有失败)将不会有空的 CustomTask 值(当您实际调用 Tooltip 时)并且会很好地分叉。然后只需添加 if(t == null) return null;到您的转换器,一切都会正常工作。

public class DateToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    CustomTask t = (CustomTask)value;
    if(t == null)
        return null;    // or other default value
    ...
}

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

我认为这种行为的原因是 DataGrid 在页面渲染和调用工具提示时渲染了整个模板,而没有数据和数据源。如果您通过我的第一个代码示例设置属性,则只有在绑定数据后才能呈现和转换器调用。

更新 要在类似情况下操作隔离列,您可以更改此列的样式或模板,而不是 RowStyle,如下例所示:

<DataGrid x:Name="customTasksDataGrid" ItemsSource="..." IsReadOnly="True" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="ID" Binding="{Binding ID}"/>
        <DataGridTextColumn Header="Klient" Binding="{Binding Name}">
            <DataGridTextColumn.ElementStyle>
                <Style TargetType="{x:Type TextBlock}">
                    <Setter Property="ToolTipService.ToolTip">
                        <Setter.Value>
                            <TextBlock Text="{Binding Path=., Converter={StaticResource converter}}"/>
                        </Setter.Value>
                    </Setter>
                </Style>
            </DataGridTextColumn.ElementStyle>
        </DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

【讨论】:

  • 谢谢老兄,这段代码对我有用,但我对下一步有问题。更改整行的背景颜色效果很好,但是如何使用这些函数更改我的数据网格中只有一个单元格的背景?当然我把ToolTipService.ToolTip改成了Background
  • @MarcinZdunek 是 this question 对您有帮助吗?只需更改 DataGridTextColumn.ElementStyle 而不是行样式。
  • 但我需要更改单元格颜色,将整个对象的信息存储在一行中。例如,单元格颜色基于 2 个对象的参数
  • @MarcinZdunek 很抱歉长时间回答。我更新了我的帖子。
猜你喜欢
  • 2013-07-17
  • 1970-01-01
  • 1970-01-01
  • 2012-09-25
  • 2010-11-14
  • 2021-02-11
  • 1970-01-01
  • 2017-01-11
  • 2019-05-25
相关资源
最近更新 更多