2011-05-29 56 views
5

Antecedentes.WPF datagrid Color de la celda según el valor de la celda preivous

Estoy desarrollando una aplicación de negociación bursátil. que obviamente tienen una vigilancia del mercado. Estoy desarrollando esta vigilancia del mercado usando Datagrid.

¿Qué hace la rejilla? Muestra los puntos de precio de una acción. Cada vez que aumenta el valor de una acción, el primer plano de la celda particular cambia a verde si disminuye se vuelve rojo.

¿Qué hice? He intentado utilizar el método del convertidor de valores y multibinding

Problema. El convertidor de valor solo proporciona el valor actual. ¿Cómo puedo pasar el valor anterior a ese convertidor?

Código:

<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> 

convertidor

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); 
    } 
} 

Respuesta

-1

Bueno, yo creo que el problema no es la cuadrícula de datos, pero el objeto que se unen a. si enlaza a una tabla de datos, los valores antiguos están incorporados (DataRowVersion). si tiene otros objetos de entidad, entonces estas entidades deben soportar los valores originales y modificados.

+0

gracias, pero me puede proporcionar un ejemplo. Como soy nuevo en WPF, no entiendo cómo enlazar objetos a la cuadrícula de datos. – Megatron

+0

No creo que 'DataRowVersion' sea la solución. Eso es útil cuando necesita acceder a la versión recibida de la base de datos y la versión local modificada. Lo que quiere el OP es el valor antiguo de la base de datos y el nuevo valor de la base de datos. – svick

3

Para cambiar el color de una celda de cuadrícula de datos recomiendo lo siguiente:

construir un modelo que implementa INotifyPropertyChanged que contiene la corriente, y el precio anterior más una propiedad que refleja el cambio en el precio (he adjunto el modelo completo al final de esta respuesta).

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

y establecer el fondo de la CellTemplate en su cuadrícula de datos en base a la variación del precio utilizando un convertidor. Nota: INotifyPropertyChanged ayuda a cambiar el color de la celda cuando cambian los valores de precio.

<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(); 
    } 
} 

Aquí está llena modelo de completitud:

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)); 
    } 
    } 
} 
Cuestiones relacionadas