Вопрос по xaml, wpf – Использование DataTrigger

1

Вот псевдокод для того, что я хочу реализовать в 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

и ниже - попытка реализации, по крайней мере, со следующими проблемами:

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

Как я могу реализовать это правильно?

Ура,
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

Как указывает тримейко, этоcould быть сделано или с мультиконвертером или внутри модели представления.

В ответ на мой ответ: «Сначала я попробовал подход с несколькими конвертерами, но с небольшим успехом, и почти опубликовал это, чтобы помочь его очистить. Затем я решил, что конвертеры лучше всего использовать для преобразования типов. Согласованный подход модели представления является, вероятно, самым простым, но это, похоже, больше работа представления, и я хотел бы посмотреть, смогу ли я сначала заставить его работать таким образом ».

Я попытался [решить эту проблему с помощью MutliConveter, опубликовавшего здесь] (Использование мультиконвертера)

Ваш Ответ

2   ответа
4

Вы должны быть в состоянии сделать это с парой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>

Они заявляют "когдаAvatarPath является нулевым ИGender это женщина ...

Further Improvement

КакDataTriggers применяются в том порядке, в котором они появляются в XAML, мы можем устранить необходимость дублирования слова «мужской». Настройки в примере с ниже:

<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>

Здесь мы говорим:

  1. Set the source to AvatarPath
  2. If AvatarPath is null, set the source to 'Img_Male'
  3. If the AvatarPath is null AND the Gender is female, set the source to 'Img_Female'
Я полагаю, что нет никакого способа повторить условия для каждого значения Пола, даже если это всегда будет Img_Male, если только это не Женщина, да? ура Berryl
Да, это то, что я думаю, должно быть исправить. У меня проблема, которую я сделал какseparate question here, Можете ли вы взглянуть на это? Berryl
@Berryl это должно быть возможно - смотрите мое обновление
1

В качестве опции вы можете использовать собственный класс конвертера и конвертировать viewmodel в источник растрового изображения. Если вы хотите использовать триггеры, вы можете использовать несколько мультидатригеров и / или мультиконвертеров, например, для случаев, когда вы хотите показать Img_Male.

Но я думаю, что эти решения не очень хороши, лучше представить свойство / логику и просто привязать источник изображения к нему и обработать эту логику представления внутри viewmodel. Используя этот подход, вы также можете написать модульные тесты для этой логики.

У меня недостаточно представителя, чтобы прокомментировать ваш второй вопрос, поэтому я напишу его здесь: входные и выходные значения многозначных преобразователей должны быть одного типа, поэтому вы получаете UnsetValue в своем примере.
Модульное тестирование изображений также проблематично, поскольку равенство изображений не предусмотрено (понятно, что так). ура Berryl
Сначала я попробовал подход с несколькими конверторами, но с небольшим успехом, и почти опубликовал это, чтобы помочь его очистить. Затем я решил, что конвертеры лучше всего использовать для преобразования типов. Согласованный подход модели представления является, вероятно, самым простым, но это, скорее, является работой представления, и я хотел бы посмотреть, смогу ли я сначала заставить его работать как таковой. ура Berryl
Логика приложения по-прежнему заключается в том, чтобы выбирать между некоторыми изображениями и показывать правильные. Viewmodel создается для накопления всей логики / свойств представления внутри, и вы можете легко кодировать новые представления без вставки копий некоторых триггеров xaml и т.д. для растрового изображения в разных логических случаях. Почему вы так боитесь писать эту логику в ВМ? Кстати, я не совсем понимаю предложение о преобразователях, но мультиконвертеры просто выводят одно значение на основе ввода нескольких значений, но не преобразуют тип.
Увидетьthis question на которые у вас могут быть ответы на некоторые вопросы, это также относится к решению vm. ура Berryl

Похожие вопросы