3

I'm looking for some advice on how to write my WPF value converters. The way I'm currently writing them, they are very specific, like (bool?,bool) => Brush, i.e. I'm writing each converter for a specific use case, in this case, the Brush is bound to an indicator showing equality information between the bool? and the bool. This obviously makes re-use very hard and I end up with a quite large list of converters.

Should I strive to write my converters in a more general way? Can I?

  • In this case, how about adding an IsEqual property to your DataContext instead? And selecting the right brush with a data-trigger? – Pieter Witvoet Aug 22 '14 at 8:22
  • Is there a way of making sure that this property p1 is triggered when the other properties p2,p3 it depends on are changed that doesn't force me to specify in p2,p3 that p1 needs to be updated? Will this be handled automatically because of my OnPropertyChanged-call in p2,p3? – Mårten Aug 22 '14 at 8:46
  • The view doesn't know that p1 depends on p2 and p3, so you do have to raise OnPropertyChanged for p1 when changing p2 or p3 somehow. I'm currently using a system that allows me to mark such properties with an attribute: [DependsOn("p2", "p3")], with some utility code that determines what events need to be raised for what properties. The main disadvantage is that it's not refactor-friendly, given that "p2" and "p3" are strings. I've seen a library that had a solution for this somewhere, but I can't find it right now... – Pieter Witvoet Aug 22 '14 at 11:05
  • Finally found that library again: github.com/StephenCleary/CalculatedProperties - haven't used it yet, but it does look useful. – Pieter Witvoet Sep 2 '14 at 14:58
1

First try to manipulate your data source to expose data in a way that matches your GUI better. Then you won't need as many converters in the first place. In the MVVM pattern the ViewModel is a representation of the Model which is better suited for binding by the view.

Then I would say try to create data-centric converters, where the converters are designed based on the data types of the input and output. Creating converters that are tailored for specific use-cases will just cause you to create lots of redundant converters.

| improve this answer | |
  • Where would you draw the line between viewmodel and view? Imagine I want to show a display (label, Visibility=Visible/Hidden) if a certain combination of data is written in some fields, like a warning or a notice. One way would be to use a multibinding converter, as described in my own anser to this post, the other would be to implement a public bool ShowNotice { get...} that has to be updated manually whenever it's dependencies are updated. To me, the previous solution seems preferable. – Mårten Mar 23 '15 at 7:59
  • Certainly, the multibinding converter could be the best way for your scenario. There may be other scenarios where it's easier to put code in a ViewModel. – M. Dudley Mar 23 '15 at 12:12
0

I solved this problem by writing a general purpose multiconverter that can take expressions and evaluate them, since it's a multibinding, it will update the value whenever one of the sources is updated, it also means I rarely have to write new converters at all. The only expense is the xaml verbosity. One example of an expression:

<CheckBox Content="{Binding Role.Name_SV}">
    <CheckBox.Background>
         <MultiBinding Converter="{StaticResource ArithmeticsConverter}">
              <Binding Source="?"/>
              <Binding Source=">="/>
              <Binding Path="Included"/>
              <Binding Path="Requirement"/>
              <Binding>
                   <Binding.Source>
                        <SolidColorBrush>LightGreen</SolidColorBrush>
                   </Binding.Source>
              </Binding>
              <Binding>
                   <Binding.Source>
                        <SolidColorBrush>Red</SolidColorBrush>
                   </Binding.Source>
              </Binding>                
         </MultiBinding>
     </CheckBox.Background>
 </CheckBox>

The function here is that the checkbox background color is LightGreen if Included >= Requirement, and Red otherwise.

I guess some people will find this horrifyingly ugly, but I rather like how it lets me describe what I want without having to worry about when things are updated, it's more declarative and less imperative.

If anyone is interested I can post the source code for the converter.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.