前景颜色未在WPF DataGrid中的选定行上更新

时间:2013-11-20 12:04:06

标签: c# wpf mvvm converter

我希望你们中的一些人可能遇到过这个问题,并且可以向我解释这里发生了什么。我尝试了一些修复(在MVVM世界中:)没有帮助,我想在必要时应用一些黑客之前理解这个问题,

我有一组三个数据网格列,它们使用值转换器作为前景色 - 绿色表示正数,红色表示负数。

大部分时间都可以正常工作,但有时候(实际上不知道何时何地)它没有。在应用程序窗口未激活(用户查看屏幕但不与其交互)的情况下正常运行大约20分钟后,可能会发生这种情况。

一条重要信息是,无论何时用户点击该行,颜色都会立即得到修复。

同样值得注意的是,整个行颜色不会更新,数字也是正确的....

对属性的所有更新都是通过调度程序上的BeginInvoke完成的,并且可能经常发生(大约每秒20次)。

Wrong colour from the foreground binding

欢迎任何想法。

(之前我认为它可能是虚拟化,但这没有帮助)

<DataGrid
  ItemsSource="{Binding Items}"
  IsReadOnly="True"
  AlternatingRowBackground="#E5E5E5"
  EnableRowVirtualization="False"
  VirtualizingStackPanel.IsVirtualizing="False"
  VirtualizingStackPanel.VirtualizationMode="Standard">

数据网格列

<DataGridTextColumn Binding="{Binding A}" Header="A" Width="85" FontWeight="Bold">
  <DataGridTextColumn.CellStyle>
    <Style TargetType="DataGridCell" BasedOn="{StaticResource NotSelectableCellStyle}">
      <Setter Property="Block.TextAlignment" Value="Right"/>
      <Setter Property="Foreground" Value="{Binding A, Converter={StaticResource colorConverter}}"/>
    </Style>
  </DataGridTextColumn.CellStyle>
</DataGridTextColumn>

转换器

public class NegativePositiveColorConverter : IValueConverter
{
    private static readonly Brush negativeBrush;

    private static readonly Brush positiveBrush;

    static NegativePositiveColorConverter()
    {
        negativeBrush = new SolidColorBrush(Colors.Red);
        positiveBrush = new SolidColorBrush(Colors.Green);
        negativeBrush.Freeze();
        positiveBrush.Freeze();
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        decimal? decimalValue = value as decimal?;
        if (!decimalValue.HasValue)
        {
            return Binding.DoNothing;
        }

        if (decimalValue < 0)
        {
            return negativeBrush;
        }

        return positiveBrush;
    }

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

源对象属性

    public decimal? A
    {
        get
        {
            return this.a; 
        }

        set 
        {                                    
            if (this.a!= value)
            {
                this.a= value;
                OnPropertyChanged("A");
            }
        }
    }

细胞风格(相当不重要)

<Style TargetType="DataGridCell" x:Key="NotSelectableCellStyle" BasedOn="{StaticResource {x:Type DataGridCell}}">
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path=Background}"/>
        </Trigger>
    </Style.Triggers>
    <Setter Property="Background" Value="{StaticResource EditableBrush}"/>
    <Setter Property="Padding" Value="3,0,3,0" />
    <Setter Property="Template" Value="{StaticResource NotSelectableDataGridCellTemplate}"/>
</Style>

<ControlTemplate x:Key="NotSelectableDataGridCellTemplate" TargetType="{x:Type DataGridCell}" >
    <Grid>
        <Border Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
            <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
        </Border>            
    </Grid>
</ControlTemplate>

1 个答案:

答案 0 :(得分:2)

好的,我已经找到了问题,感谢(似乎显而易见,但由于某些原因,我之前没有遵循这条道路)来自@Groo的建议。我刚刚在转换器和属性设置器中添加了大量日志记录,并注意到除了我点击网格表面之外,其中一个行转换器永远不会被执行。

对于代表所选项目的行(以及每次根据首先添加的行而不同的行)都会发生这种情况。

因为我的风格没有显示选择(请参阅我的问题中的'单元格样式(而非重要)部分),我不会注意到有关失败行的任何特定内容。

我相信一个可能的解决方法是在选择任何项目时将SelectedItem设置为null。为什么在选择项目时不更新前景我不确定。