Умный антипаттерн WPF UI: какой объем логической обработки подходит в XAML?

Я использую WPF и обнаружил, что MVVM чаще всего используется с WPF, поощряя перенос логики представления в ViewModel и минимизацию кода программной части.

Однако через некоторое время я обнаружил, что вкладываю больше логики в рассмотрение и делаю такие вещи (XAML):

1 - Создание строки из нескольких элементов:

<TextBlock>
    <Run Text="{Binding Prop1}" />
    <!--<Run Combined with string.Format />-->
    <Run Text="," />
    <Run Text="{Binding Prop2}" />
</TextBlock>

2 - Перенос условной логики в триггеры данных:

<TextBox>
    <TextBox.Resources>
        <Style TargetType="TextBox">
            <Style.Triggers>
                <DataTrigger Binding="{Binding SomeProperty}" Value="value1">
                    <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
                <DataTrigger Binding="{Binding SomeProperty}" Value="value2">
                    <Setter Property="Visibility" Value="Collapsed" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBox.Resources>
</TextBox>

3 - Использование ContentControl в сочетании с несколькими шаблонами данных для содержимого разного типа:

<UserControl.Resources>
    <DataTemplate x:Key="Template1" >
        <ContentControl HorizontalContentAlignment="Stretch" Content="{Binding Item}">
            <ContentControl.Resources>
                <Style TargetType="ContentControl">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding HasAnyItem}" Value="True">
                            <Setter Property="ContentTemplate" Value="{DynamicResource Template2}" />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding HasAnyItem}" Value="False">
                            <Setter Property="ContentTemplate" Value="{DynamicResource Template1}" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Resources>
        </ContentControl>
    </DataTemplate>

    <DataTemplate x:Key="Template2" >
        ...
    </DataTemplate>
<UserControl.Resources>
...
<ContentControl ContentTemplate="{StaticResource Template1}"  Content="{Binding}"/>

и этот список продолжается, но я предполагаю, что вы имеете общее представление о том, о чем я говорю. Я знаю, что некоторые из этих функций в чем-то прекрасны в WPF.

Но когда дело доходит до ремонтопригодности и гибкости, есть ли лучший способ обработки логики? Делает ли это мой пользовательский интерфейс более чем достаточно умным, что было антипаттерном в дни форм Windows?


person Naser Asadi    schedule 24.07.2013    source источник


Ответы (2)


Хорошая мысль, для меня идея в основном состоит в том, что можно тестировать и как писать для этого тесты. В большинстве случаев ViewModel не является прямым (индивидуальным) соответствием вашей презентации (View).

Идея, когда дизайнер проектирует ваше представление с использованием XAML (Blend / Designer) для меня, указывает на то, что в нем нет бизнес-логики, и для них необходимо определение бизнес-объекта.

Когда у вас есть модульные тесты, вы можете доказать, что его можно поддерживать.

Так что все, что вы упомянули, если они чисто презентационные, я бы не возражал. Но если это повлияет на состояние бизнес-данных, я бы предпочел иметь это в ViewModel и использовать конвертеры для соответствующей презентации.

person is_this_the_way    schedule 24.07.2013
comment
интересное руководство - person Naser Asadi; 27.07.2013

Полностью согласен с bjoshi, в основе XAML отсутствует бизнес-логика. Я хотел бы добавить еще три момента, которые вы можете учесть:

  1. Представление. Когда вы добавляете больше логики в XAML и делаете пользовательский интерфейс более мощным, вы также получаете возможность снижения производительности. В вашем примере «Выполнить» не рекомендуется с точки зрения производительности. Также вы используете DynamicResource в своем третьем примере, чего также можно было бы избежать, если бы вы могли найти подход, используя вместо этого StaticResource.

  2. Отладка. Отладка может быть одним из недостатков WPF, поскольку WPF управляет привязкой данных, триггерами и т. Д. Для вас, и эти вещи являются косвенными. Например, как вы отлаживаете триггеры? Если представление простое и пассивное, его также может быть проще отладить.

  3. Гибкость. В первом примере вы помещаете логику организации Pro1 и Pro2 в представление, а не в модель представления. Предполагая, что в будущем вы захотите изменить "," на ":", например, вам необходимо изменить представление. Этот случай простой, но другие могут быть трудными. Конечно, ни один из этих случаев не подлежит модульному тестированию. Возможно, вам потребуется спрогнозировать изменение и сложность изменения.

Надеюсь, это поможет.

person Bill Zhang    schedule 24.07.2013
comment
Ты прав. smart UI в WPF сложно отлаживать. На самом деле автоматизация пользовательского интерфейса не поддерживается в XAML. - person Naser Asadi; 27.07.2013
comment
На самом деле это возможно, автоматизация пользовательского интерфейса в WPF. Вы слышали / читали о White (TestStack)? - person is_this_the_way; 28.07.2013
comment
@bjoshi: Нет, довольно интересно. Он был построен на основе библиотеки автоматизации пользовательского интерфейса Microsoft. - person Naser Asadi; 29.07.2013
comment
В качестве продолжения здесь есть несколько хороших обсуждений, stackoverflow.com/questions/1249041/ - person is_this_the_way; 29.07.2013