2011-05-29 126 views
5

背景。WPF datagrid单元格颜色取决于preivous单元值

我正在开发股票交易应用程序。 明显有市场观察。 我正在开发这个市场手表使用Datagrid

网格是做什么的? 它显示股票的价格点。 每当股票价格上涨时,特定单元格前景变为绿色,如果它减少,它将变为红色。

我做了什么? 我试图使用值转换器方法和多重绑定

问题。 值转换器只给出当前值。 我如何将旧值传递给该转换器。

代码:

<wpfTlKit:DataGrid.CellStyle> 
      <Style TargetType="{x:Type wpfTlKit:DataGridCell}"> 
       <Setter Property="Background"> 
        <Setter.Value> 
         <MultiBinding Converter="{StaticResource myHighlighterConverter}" 
             > 
          <MultiBinding.Bindings> 
           <Binding RelativeSource="{RelativeSource Self}"></Binding> 
           <Binding Path="Row" Mode="OneWay"></Binding> 
           <Binding ElementName="OldData" Path="Rows"></Binding> 
          </MultiBinding.Bindings> 
         </MultiBinding> 
        </Setter.Value> 
       </Setter> 
      </Style> 
     </wpfTlKit:DataGrid.CellStyle> 

转换

public class HighlighterConverter : IMultiValueConverter 
{ 
    #region Implementation of IMultiValueConverter 

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (values[1] is DataRow) 
     { 
      //Change the background of any cell with 1.0 to light red. 
      var cell = (DataGridCell)values[0]; 
      var row = (DataRow)values[1]; 
      var columnName = cell.Column.SortMemberPath; 

      if (row[columnName].IsNumeric() && row[columnName].ToDouble() == 1.0) 
       return new SolidColorBrush(Colors.LightSalmon); 

     } 
     return SystemColors.AppWorkspaceColor; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new System.NotImplementedException(); 
    } 

    #endregion 
} 

public static class Extensions 
{ 
    public static bool IsNumeric(this object val) 
    { 
     double test; 
     return double.TryParse(val.ToString(), out test); 
    } 

    public static double ToDouble(this object val) 
    { 
     return Convert.ToDouble(val); 
    } 
} 

回答

-1

嗯,我认为这个问题是不是在DataGrid,但对象绑定到。如果绑定到数据表,则旧值(DataRowVersion)内置。如果你有其他的实体对象,那么这个实体需要支持原始值和修改值。

+0

感谢,但你可以给我提供一个例子。是WPF的新手,我不明白如何将对象绑定到数据网格。 – Megatron 2011-05-29 08:19:54

+0

我不认为'DataRowVersion'是解决方案。当您需要访问从数据库接收的版本和本地修改版本时,这非常有用。 OP要的是数据库的旧值和数据库的新值。 – svick 2011-05-29 11:45:36

3

要改变DataGrid单元格的颜色我提出以下建议:

构建一个实现INotifyPropertyChanged模型包含当前和以前的价格加在反映价格变化的属性(我已经把它贴在这个答案的最后的完整模型)。

public double ChangeInPrice 
{ 
    get 
    { 
    return CurrentPrice - PreviousPrice; 
    } 
} 

并使用转换器基于价格的变化在您的DataGrid中设置CellTemplate的背景。 注意:当价格变化时,INotifyPropertyChanged有助于更改单元格的颜色。

<DataGridTemplateColumn.CellTemplate> 
    <DataTemplate> 
    <TextBlock 
     Text="{Binding Path=CurrentPrice}" 
     Background="{Binding Path=ChangeInPrice, Converter={StaticResource backgroundConverter}}" > 
    </TextBlock> 
    </DataTemplate> 
</DataGridTemplateColumn.CellTemplate> 


[ValueConversion(typeof(object), typeof(SolidBrush))] 
public class ObjectToBackgroundConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
    SolidColorBrush b = Brushes.White; 

    try 
    { 
     double stock = (double)value; 
     if (stock > 0) 
     { 
     b = Brushes.Green; 
     } 
     else if (stock < 0) 
     { 
     b = Brushes.Red; 
     } 
    } 
    catch (Exception e) 
    { 
    } 

    return b; 
    } 

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

这里是一个充满完整型号:

public class Stock : INotifyPropertyChanged 
{ 
    public Stock(string stockName, double currentPrice, double previousPrice) 
    { 
    this.StockName = stockName; 
    this.CurrentPrice = currentPrice; 
    this.PreviousPrice = previousPrice; 
    } 

    private string _stockName; 
    public String StockName 
    { 
    get { return _stockName; } 
    set 
    { 
     _stockName = value; 
     OnPropertyChanged("StockName"); 
    } 
    } 

    private double _currentPrice = 0.00; 
    public double CurrentPrice 
    { 
    get { return _currentPrice; } 
    set 
    { 
     _currentPrice = value; 
     OnPropertyChanged("CurrentPrice"); 
     OnPropertyChanged("ChangeInPrice"); 
    } 
    } 

    private double _previousPrice = 0.00; 
    public double PreviousPrice 
    { 
    get { return _previousPrice; } 
    set 
    { 
     _previousPrice = value; 
     OnPropertyChanged("PreviousPrice"); 
     OnPropertyChanged("ChangeInPrice"); 
    } 
    } 

    public double ChangeInPrice 
    { 
    get 
    { 
     return CurrentPrice - PreviousPrice; 
    } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnPropertyChanged(string propertyName) 
    { 
    PropertyChangedEventHandler handler = PropertyChanged; 

    if (handler != null) 
    { 
     handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
    } 
}