【问题标题】:WPF smart UI anti-pattern : How much logic processing is appropriate in XAML?WPF 智能 UI 反模式:XAML 中适合多少逻辑处理?
【发布时间】:2013-12-25 21:28:50
【问题描述】:

我正在使用 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 的魅力所在。

但是在可维护性和灵活性方面,有没有更好的逻辑处理方式?它是否让我的 UI 变得足够智能,这在 Windows 窗体时代是一种反模式?

【问题讨论】:

    标签: wpf xaml mvvm anti-patterns


    【解决方案1】:

    很好的想法,对我来说这个想法主要是什么是可测试的以及如何为它编写测试。大多数情况下,ViewModel 并不是您的演示文稿(视图)的直接(一对一)对应关系。

    对我来说,设计师使用 XAML(Blend/Designer)设计您的视图的想法表明,对于他们而言,业务对象定义没有必要的业务逻辑。

    当您进行单元测试时,您可以证明它是可维护的。

    因此,如果您提到的所有事情都是纯粹的介绍,那么我真的不介意。但是,如果这会影响业务数据的状态,那么我宁愿在 ViewModel 中使用它并使用转换器进行适当的演示

    【讨论】:

    • 有趣的指南
    【解决方案2】:

    完全同意 bjoshi,基线是 XAML 上没有业务逻辑。我想补充三点您可以考虑:

    1. 性能。当您在 XAML 上添加更多逻辑并使 UI 更强大时,也会带来性能影响的潜力。在您的示例中,从性能角度来看,不推荐使用“运行”方式。此外,您在第三个示例中使用 DynamicResource,如果您可以找到使用 StaticResource 的方法,也可以避免这种情况。

    2. 调试。调试可能是 WPF 的缺点之一,因为 WPF 为您管理数据绑定、触发器等,而这些都是间接的。例如,您如何调试触发器?如果视图简单且被动,也可能更容易调试。

    3. 灵活性。在第一个示例中,您将组织 Pro1 和 Pro2 的逻辑放在视图而不是视图模型上。假设将来您想将“,”更改为“:”,例如,您必须修改视图。这种情况很简单,但其他情况可能很困难。当然,这两种情况都不是可单元测试的。您可能需要预测变化和变化的复杂性。

    希望对你有帮助。

    【讨论】:

    • 你是对的。 WPF 中的智能 UI 很难调试。实际上 XAML 不支持 UI 自动化。
    • 实际上是有可能的,WPF 中的 UI 自动化。你听说过/读过 White (TestStack) 吗?
    • @bjoshi:不,很有趣。它建立在 Microsoft 的 UI 自动化库之上。
    • 作为后续,这里有一些很好的讨论,stackoverflow.com/questions/1249041/…
    猜你喜欢
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 2014-12-16
    • 1970-01-01
    • 2013-07-02
    • 2017-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多