I have a generic control which displays an editor based on the type property inside a ViewModel. Currently it's implemented using Control
, ControlTemplate
and DataTrigger
like this -
<Control
x:Name="MainControl"
Grid.Column="1"
TargetUpdated="OnTargetUpdated">
<Control.Style>
<Style>
<Style.Triggers>
<DataTrigger
Binding="{Binding Path=EditorType}"
Value="{x:Static view:EditorType.Bool}">
<Setter
Property="Control.Template"
Value="{StaticResource boolTemplate}" />
</DataTrigger>
<DataTrigger
Binding="{Binding Path=EditorType}"
Value="{x:Static view:EditorType.Text}">
<Setter
Property="Control.Template"
Value="{StaticResource textTemplate}" />
</DataTrigger>
<DataTrigger
Binding="{Binding Path=EditorType}"
Value="{x:Static view:EditorType.Integer}">
<Setter
Property="Control.Template"
Value="{StaticResource integerTemplate}" />
</DataTrigger>
...
....
</Style.Triggers>
</Style>
</Control.Style>
</Control>
Now, same can be achieved using ContentPresenter
, DataTemplate
and DataTemplateSelector
like this -
<local:EditorTemplateSelector
BoolEditorTemplate="{StaticResource boolTemplate}"
TextEditorTemplate="{StaticResource textTemplate}"
IntegerEditorTemplate="{StaticResource integerTemplate}"
...
....
x:Key="EditorTemplateSelector">
</local:EditorTemplateSelector>
<ContentPresenter
ContentTemplateSelector="{Binding Source={StaticResource EditorTemplateSelector}}"
Content="{Binding}"
TargetUpdated="OnTargetUpdated">
</ContentPresenter>
// Template selector returning appropriate template based on type
I feel the second approach, using DataTemplateSelector
is better but would like to know from you -
Which one is better and why?
Will there be any performance difference in two?
I've heard that DataTemplateSelectors
do not update the template if the value they're based on changes, and because of this I usually don't use them.
My preferred method is actually to use DataTemplates.
<MyControl.Resources>
<DataTemplate TargetType="{x:Type local:BooleanModel}">
<local:BooleanView />
</DataTemplate>
<DataTemplate TargetType="{x:Type local:IntegerModel}">
<local:IntegerView />
</DataTemplate>
...
</MyControl.Resources>
Second, if I want to change the template based on a property rather than the object type, I tend to use DataTriggers
. This is because if that property ever gets changed, the PropertyChange notification will automatically tell the UI that it has changed and to update the template. I do not believe DataTemplateSelectors
do this automatically. I also prefer to see the template selection logic in my XAML, not have it hidden in a TemplateSelector file, but that's just personal preference.
And my last choice is to use a DataTemplateSelector
. I almost never use one in a WPF application, although I often do in Silverlight since it doesn't support my preferred method of using implicit DataTemplates
(yet)
I am not aware of any significant performance differences between the two, although I would be interested if someone can tell me otherwise.
You've two questions here:)
- Where to make a decsion in
XAML
(DataTriggers
) or in codeTemplateSelector
- What are you overriding the whole
Style
or just theDataTemplate
. In your first sample you overrideStyle
, in the second one -DataTemplate
.
Here're my 2c:
I'd stick with the Triggers, as you'll get an unbeatable flexibility level with them - a new editor for the price of new resource and a trigger all in XAML - what can be better? There's one potential caveat, related to DataTrigger usage - it may cause data leaks.
Talking of Style
vs DataTemplate
choice I's stick again with the Style
. It might be a bit heavier visual tree wise, but it'll give you the ultimate control over the apperance of you editors.
In particular, some properties can only be defined at a Style
level, using Style
Setters
's.
Defining then @DataTemplate
level simply won't work as your DataTemplate
content is not an immediate child of your control container (there's an extra level - the actula Control). If you've no such properties, ControlTemplates
are good too, and probably faster(?).
I'm also not a fan of DataTemplateSelector, but I guess you could use them if your selector-evaluation consists of more than type checking, e.g. if x>5 && dayOfWeek==Tue && isFullMoon(today)
then template1.
I would suggest the answer is more one of do you think a control
is necessary. You get a whole bunch of functionality with a control
that is not really available with a DataTemplate
. You can add DependencyProperties
, events
, functions
etc etc. But do you need this? If you don't then a control might be overkill.
来源:https://stackoverflow.com/questions/8926024/controltemplate-with-datatrigger-vs-datatemplate-with-datatemplateselector