问题
Here is pseudo code for what I want to implement in xaml
IF vm.AvatarFilePath IS NOT NULL THEN
Image.Source = {Binding AvatarPath}
ELSE
If vm.Gender == {x:Static vm:Gender.Female} THEN
Image.Source = {StaticResource Img_Female}
ELSE
Image.Source = {StaticResource Img_Male}
ENDIF
ENDIF
and below is an implementation attempt with at least the following issues:
- how does it know the AvatarPath was null and that we care about Gender?
- is there a way to do ELSE, so I can specify the Gender.Male resource only once instead of once each for
How can I implement this properly?
Cheers,
Berryl
xaml attempt 1
<DataTemplate x:Key="AvatarPathTemplate">
<Image x:Name="avatarImage" Source="{Binding AvatarPath}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Gender}" Value="{x:Static vm:Gender.Female}">
<Setter Property="Sourrce" Value="{resx:Resx Img_Female}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Gender}" Value="{x:Static vm:Gender.Male}">
<Setter Property="Sourrce" Value="{resx:Resx Img_Male}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Gender}" Value="{x:Static vm:Gender.Unknown}">
<Setter Property="Sourrce" Value="{resx:Resx Img_Male}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Gender}" Value="{x:Static vm:Gender.Unspecified}">
<Setter Property="Sourrce" Value="{resx:Resx Img_Male}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
update
As trimeyko points out, this could be done either with a multiconverter or inside of a view model.
Per my answer back: "I actually tried the multiconverter approach at first, with modest success, and almost posted that to help clean it up. Then I decided that converters are best left to actually converting types. Agreed the view model approach is probably easiest but this does seem more to be the view's job, and I'd like to see if I can get it to work as such first."
I made my attempt at [solving this with a mutliConveter posting here] (MultiConverter usage)
回答1:
You should be able to do this with a couple of MultiDataTriggers:
<DataTemplate x:Key="AvatarPathTemplate">
<Image x:Name="avatarImage" Source="{Binding AvatarPath}"/>
<DataTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding AvatarPath}" Value="{x:Null}" />
<Condition Binding="{Binding Gender}" Value="{x:Static vm:Gender.Female}"/>
</MultiDataTrigger.Conditions>
<Setter Property="Source" Value="{resx:Resx Img_Female}"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding AvatarPath}" Value="{x:Null}" />
<Condition Binding="{Binding Gender}" Value="{x:Static vm:Gender.Male}"/>
</MultiDataTrigger.Conditions>
<Setter Property="Source" Value="{resx:Resx Img_Male}"/>
</MultiDataTrigger>
<!-- etc... -->
</DataTemplate.Triggers>
</DataTemplate>
These are stating 'when AvatarPath
is null AND Gender
is female...'
Further Improvement
As DataTrigger
s are applied in the order in which they appear in the XAML, we can remove the need for duplication of the 'Male' settings in the example with the below:
<DataTemplate x:Key="AvatarPathTemplate">
<Image x:Name="avatarImage" Source="{Binding AvatarPath}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding AvatarPath}" Value="{x:Null}">
<Setter Property="Source" Value="{resx:Resx Img_Male}"/>
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding AvatarPath}" Value="{x:Null}" />
<Condition Binding="{Binding Gender}" Value="{x:Static vm:Gender.Female}"/>
</MultiDataTrigger.Conditions>
<Setter Property="Source" Value="{resx:Resx Img_Female}"/>
</MultiDataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
Here we are saying:
- Set the source to
AvatarPath
- If
AvatarPath
is null, set the source to 'Img_Male' - If the
AvatarPath
is null AND theGender
is female, set the source to 'Img_Female'
回答2:
As an option you can use custom converter class and convert viewmodel to bitmap source. If you wish to use triggers, then you can use some multidatatriggers and/or multiconverters for example for cases when you want to show Img_Male.
But these solutions isn't really good I think, better to introduce property/logic and simply bind image source to it and handle these view logic inside viewmodel. Using this approach you can write unit tests for this logic also.
来源:https://stackoverflow.com/questions/10636061/datatrigger-usage