2011-05-29 145 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)); 
    } 
    } 
}