I have 2 different ProgressBars with 2 different custom styles. In each of them, Color of the ProgressBar is Calculated based on Maximum and Value (with 2 different formulas).
I see that the type of the ConverterParameter in a converter is String.
Now I'm wondering should I write 2 different MultiValueConverters for each of them, or write a single MultiValueConverter with a Parameter and let the Parameter decide which formula should be executed.
These 2 ProgressBars are probably the bottle-neck of my MVVM's View, so I need to know which one is better in performance?
Write one converter - it makes no sense to have multiple converters for the same purpose.
Indicate which formula you want to use by using an enumeration - the value can be explicitly mentioned in the XAML.
If you want to bind external values in to your converter it will need to derive from DependencyObject and the properties will have to be dependency properties.
Related
I'm new to wpf and now I have a problem. I have a model class say Customer and I've created a DataTemplate with TargetType property set to Customer. It works good. But I actually want two different templates like one for just displaying the record and another for in-place editing. Is it possible to specify two different templates for same datatype based on some creteria?
And I want to switch this template based on some property on ViewModel like when IsEditmode is True.
Or am I doing it wrong? Should I use styles instead?
Your approach seems to be perfectly fine.
You can create a DataTemplateSelector which will allow you to choose a data template based on arbitrary criteria from code behind.
I often use these to decide which template to use based on a enum-type property.
There are two easy ways I can think of, ofcourse there are other ways based on the complexity and architecture you want to follow.
Define DataTemplate with 'Key' and specifically call that either using StaticResource/DynamicResource Binding.
You can have a DataTrigger inside the datatemplate which makes some parts of the template visible/collapsed based on your 'EditMode' property
If I wanted to hide(or change visibility, color, etc) of an element in WPF is it better to use DataTrigger or a binding with a converter?
Sounds like two ways to achieve the same goal. When is it better to user one over another?
I can tell you about my experience.
I use databinding with converters for the following cases:
For the Visibility property (there is the built-in converter in WPF).
In Silverlight applications (although there are silverlight-compatible data triggers in the Microsoft.Expression.Interactions library, they are not as convenient as WPF triggers).
If the source object contains many possible values. Enum to image converter, for example, it is easier to write 5 if-else clauses than 5 datatriggers.
Datatriggers:
If I want to change several different properties at once (background, visibility, thickness).
For brushes (It isn't easy to create brush in C# code by using the hex-number of the color).
If I want to apply static resources.
They can be used for displaying animation and running storyboards.
Sometimes I prefer the MVVM approach: I create additional properties of the necessary type in the viewmodel so that they can be bound directly without converting.
The short answer is it depends.
Data Triggers only offer equality operations against a single data source.
If you need to have parameters or multi-value binding you would need to use a converter.
If I had a label on a view that I wanted to have the width equal to the width of two columns in one of my grids on the same view, how would I set up the binding without using a converter? Should I use properties to preform my calculation and store a value? It is my intention that if the view's grid size changes then this label's size will also change to match the new width of the two columns.
And where should I put this logic? I am trying to follow MVVM pattern but I see that a lot of threads about "converters in MVVM" say to put the logic into the viewmodel.
I tried to implement this behavior with dependency properties on my view since my viewmodel technically has no knowledge of my view (so how would my viewmodel know how wide my columns currently are?). This goes against what I have read online though. When implementing this behavior I noticed that I cannot reference my columns by name unless my property is not static, but dependency properties are static so I am not sure how to shuffle my values around without creating yet more properties to hold values.
Can someone provide help here? I feel like i'm overcomplicating this. I just need this label to sit over these two columns however they stretch. It just provides a visual grouping of related fields in the grid. Once I can do this first one, the other two should be equally similar.
My rule of thumb is if it's "View" related then keep it away from the ViewModel. From your description this sounds like it's purely view related, so I would just use logic in either the codebehind or a converter.
Now what I don't understand is why you are reluctant to use Converters. With converters you certainly don't want to store business logic that is going to lead to confusion or pain points for refactoring, but if you have some value that needs to be converted for a specific view operation then Converters are exactly what you should be using.
So my advice is Converters ... if it's View related then feel free to use Converters and Codebehind ... in fact you should use them and not the ViewModel.
Does that help?
Any Assumption or rule is there, when we can use DataTrigger and when we can use Converter?
DataTriggers are used to change styling depending on a specific value. For example change the TextBlock to red when its content is a number below 0.
Converter is used to convert a value to another type of value. For example to convert a boolean to a Visibility enum value
A DataTrigger can only be used to check for a specific value - it cannot e.g. check for ranges. A DataTrigger can be combined for multiple conditions (MultiTrigger) - a ValueConverter can only convert one value to another. (Of course, a MultiValueConverter can take many values (and listen for updates on all of them - but still only return one value.))
The two can be used in conjunction, though - say, having a ValueConverter that checks if the value is below 50 (returning true) to activate the DataTrigger (put it in the Binding of the DataTrigger).
So, there is no golden rule in my book - only circumstances that might make one of them unusable (or very, very hard to apply).
The system I'm working on uses a large number of custom value types internally. I'm working on a prototype UI using WPF. WPF does not know how to display the custom types. I know that I can write a custom ValueConverter to do this, but I really don't want to have to specify the use of a converter every time I bind to a class in my XAML.
Is there an Interface I can implement in the custom value type that will let WPF know how to display it natively?
Or, is there a way I can specify an application-wide value converter that will apply to any instance of our custom type, without having to specify the ValueConveter in every binding expression?
Aha! Figured it out. I needed to write a TypeConverter and apply it to my custom types. This allows WPF to automatically figure out how to handle them without having to specify a template or converter in the XAML.
http://msdn.microsoft.com/en-us/library/ayybcxe5.aspx
You should be able to specify a DataTemplate for your value type, and put it in your application resources. This would determine how your Value type is displayed globally.
I'm sorry if this is so obvious it's stupid, but why don't you override ToString() in your value types?