Hi! In WPF it's better to create a property "complex" (i.e. of type "Visibility") or a property simple (i.e. of type boolean) and then using a converter to bind the property? The first way is shorter to write, but I don't know what is better about the performances. Thank you! Pileggi
The performance hit of using a converter is going to be negligible. What you should base the choice on, though, is where you're implementing the property.
A Visibility
property only makes sense on a class in the UI layer (a custom control or maybe a viewmodel). If you're creating a property on a model class that just happens to drive your UI in this instance, it would make more sense to use a boolean and a converter.
EDIT: added (slightly contrived) example
For example, imagine you have a data class (a model) for an editable object called Foo
, and a Foo
can be "simple" or "advanced." An "advanced" Foo
will display extra editing controls in the UI - so we need to bind the Visibility
property of the advanced edit panel to some property.
Your Foo
class could have a property to indicate whether it's advanced or not. That property should definitely be a boolean - NOT a Visibility
- because your Foo
class shouldn't care about any specifics of the UI that's displaying it. So a boolean Foo.IsAdvanced
would be a suitable property.
In this case, you could bind directly to Foo.IsAdvanced
and use a converter. What you definitely don't want to do is create a Visibility
property Foo.AdvancedEditControlVisibility
, because Foo
is supposed to be back-end data class.
If you wanted to create a property that doesn't require a converter, you should create that property in a higher class, one specific to your UI. Some architectural patterns would call this a "ViewModel" class - it's a class that presents the model in a way that the data is more suitable for display by the UI. So, you might create a class that takes a Foo
and exposes an AdvancedEditControlVisibility
property that is based on the value of its Foo.IsAdvanced
.
In this case, you could bind directly to the property on the viewmodel with no converter. Note that ultimately you've done the conversion anyway - you've just made it a more explicit part of your code, instead of being confined to markup.
The thought process here is that the viewmodel is a "higher level" class - one that wraps your data class and includes UI-specific logic - and so it's more appropriate to include code that is specific to your UI. Ideally, you should take each class of your project in turn and make sure that it has a specific purpose: if Foo
is a business-object that holds data, why should it expose (or even care about!) the visibility of some piece of UI used to display it? What would happen if you put a Foo
in a commandline app, or a web application? If you have WPF-UI-specific logic in a business class then your encapsulation is wrong - but separation of concerns in this manner is one of the hardest things to get right sometimes.
And performance-wise you'll notice little difference. :-)
If the question is about performance, the first option will have a negligible speed over the second as the latter involves boxing/unboxing.
But it is recommended to have the properties, Data-Oriented and change the view accordingly either using converters or DataTriggers.
I don't think any of the two options will have a major performance issue. More important is who will be the end user of the property.
In my project we are displaying these type of properties to user in a property grid; so it makes more sense to have a boolean property, so that it is displayed as a checkbox to user. If we go with Visibility property then it will be displayed as a combobox having Visible, Hidden and Collapsed options. This can be confusion for non technical users.
As Dan said - If your property is declared in viewmodel/presentation layer and only you will use this property in views(xaml or code) then it makes more sense to have complex property. So that you can directly bind that. But if you are doing it somewhere else say your BL then it makes more sense to have it as bool.