-1

I have a GridView where columns can be bound to numeric values. I use it to switch the style based on a view model value. I.e if it's negative, I want to display red, if it's positive then it should display black, and if it's 0 I don't want to display a value at all.

My problem is with the re-usability of the StyleSelector

public class AmountStyleSelector : StyleSelector 
{
   public override Style SelectStyle(object item, DependencyObject container)
   {

      if (!(item is TransactionVm tran))
         return null;

      var header = ((GridViewBoundColumnBase)((GridViewCellBase)container).Column).Header;

      Style Local(decimal value)
      {
         if (value == 0) return Empty;   
         return value <= 0 ? Negative : Positive;
      }

      // OMG what, surely there is a better way, 
      // other than switch on the column header name?
      return header switch
         {
            "Debit" => Local(tran.Amount.Debit),
            "Credit" => Local(tran.Amount.Credit),
            "Total" => Local(tran.Amount.Total),
            "Balance" => Local(tran.Amount.Balance),
            _ => Positive
         };
   } 

   public Style Negative { get; set; }
   public Style Positive { get; set; }
   public Style Empty { get; set; } 
}

As you can see, it's hardwired to the column name to pick the view model value (which is actually the bound value).

Is there a way that can work on the actual bound value instead?

Ignoring the visual tree here, it would be nice to be able to do something like this…

var column = ((GridViewBoundColumnBase)((GridViewCellBase)container).Column);
var value = column.BindingProperty.GetActualTrueToGodBoundValue();
Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
TheGeneral
  • 79,002
  • 9
  • 103
  • 141
  • 1
    I don't see a good way to answer the question as asked. I mean, you haven't even explained where the style is applied precisely, never mind provided a good [mcve]. That said, I don't think I'd use a style selector for this purpose; instead, I'd just bind the value directly to the background, using a converter for the binding. I'd pass an array of colors (defined as a resource) as the converter parameter, and have the converter select the appropriate color from the array based on the source value for the binding. – Peter Duniho Mar 28 '20 at 04:18
  • 1
    Frankly, your question seems to have an [XY Problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) flavor to it, as you're asking about a specific, but probably impossible, way to solve some broader problem, even as there are better ways to approach it. ... – Peter Duniho Mar 28 '20 at 04:25
  • 1
    I have the sense that the question is really a duplicate of the many similar ones already asked: https://stackoverflow.com/questions/60286718/change-wpf-datagrid-column-cell-background-color-based-on-values, https://stackoverflow.com/questions/16645688/how-to-set-background-of-a-datagrid-cell-during-autogeneratingcolumn-event-depen, https://stackoverflow.com/questions/5549617/change-datagrid-cell-colour-based-on-values. – Peter Duniho Mar 28 '20 at 04:25
  • Your paints are valid, and the context is definitly skewed because im using a gridview that has a selector on the column, which i thought id take advantage of as i need to adjust a couple of properties, it was nice and neat (to a certain degree). However, your point about a converter would be the standard approach, even if i needed to make a couple of them to achieve the desired result. They would be more granular and not locked to the context of the tree it was in. Ill take your thoughts into consideration, and may well just hit a couple of converters to change the properties i need – TheGeneral Mar 28 '20 at 04:37
  • @PeterDuniho i can delete the question, or you can give an honest answer and ill happily mark it as correct, maybe it could spark some neurons in someone falling down a similar path – TheGeneral Mar 28 '20 at 04:40

1 Answers1

1

where columns can be bound to numeric values. I use it to switch the style based on a view model value.

I cannot speak to your current design, but when items need to be altered such as visibility, isEnabled and colors...why not do a multibuilding to the target value and use a converter which will take in 1 to many items and return a color/brush?

It seems that the current design has coded you into the proverbial hole. A style for the most part should be used to provide a structure to the visible view, while the specifics of that view can be altered using converters or data triggers; not changing a whole style (of the view) completely for one color change.

Simplify your design.

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
  • Once again, i share the sentiments and the spirit in how they were given. i definitely was trying to avoid a trigger on a cell. I was also trying to style the cell in a specific way, to avoid repetition through the several properties i need to change and all the other grids and situations it gets used. as such the style selector worked well and was just one small non verbose addition to the cell i wanted to change. Anyway all good, thanks for the answer – TheGeneral Mar 28 '20 at 04:53
  • Anyone who has done wpf has experienced what you have. Taken an example or two of doing things in one way and trying to put in a third factor and watching it fall like a house of cards. If you are stuck, create a small example of what is needed outside the project to try different things or post here on SO. GL. :-) – ΩmegaMan Mar 28 '20 at 23:08