2011-05-29 6 views
5

Arrière-plan.WPF dataagrid Couleur de la cellule en fonction de la valeur de la cellule précisée

Je développe une application de négociation d'actions. Qui a évidemment une surveillance du marché. Je développe cette veille de marché en utilisant Datagrid.

Que fait la grille? Il affiche les points de prix d'un stock. Chaque fois qu'une valeur de stock augmente, le premier plan de la cellule devient vert s'il diminue, il devient rouge.

Qu'est-ce que j'ai fait? J'ai essayé d'utiliser la méthode du convertisseur de valeur et la liaison multiple

Problème. Le convertisseur de valeur donne uniquement la valeur actuelle. Comment puis-je passer l'ancienne valeur à ce convertisseur.

code:

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

Converter

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

Répondre

-1

Eh bien, je pense que le problème est pas le DataGrid, mais l'objet se lier à. si vous liez à un datatable, les anciennes valeurs sont intégrées (DataRowVersion). Si vous avez d'autres objets d'entité, ces entités doivent prendre en charge les valeurs d'origine et modifiées.

+0

merci, mais pouvez-vous me donner un exemple. étant nouveau pour WPF, je ne comprends pas comment lier des objets à datagrid. – Megatron

+0

Je ne pense pas que 'DataRowVersion' soit la solution. C'est utile lorsque vous avez besoin d'accéder à la version reçue de la base de données et de la version locale modifiée. Ce que l'OP veut, c'est l'ancienne valeur de la base de données et la nouvelle valeur de la base de données. – svick

3

Pour changer la couleur dans une cellule DataGrid Je recommande ce qui suit:

Construire un modèle qui implémente INotifyPropertyChanged qui contient le courant et le prix précédent plus une propriété qui reflète le changement dans le prix (j'ai joint le modèle complet à la fin de cette réponse).

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

Et mettre l'arrière-plan de la CellTemplate dans votre DataGrid en fonction de la variation du prix en utilisant un convertisseur. Remarque: INotifyPropertyChanged permet de modifier la couleur de la cellule lorsque les valeurs de prix changent.

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

Voici modèle complet est complet:

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