WPF数据绑定与条件表达式

4

我正在使用MVVM模式,我的视图的数据上下文具有一个名为Customer的属性。现在我想根据Customer.CustomerID属性的值来绑定我的文本框的IsEnabled属性。如果它大于0,那么它应该启用,否则禁用。

我知道我可以很容易地在视图模型中添加一个bool属性,并将其绑定到我的文本框的IsEnabled属性,但这似乎有些过度设计。

1个回答

13

有几个选项。

首先,您可以使用DataTrigger

<TextBox>
    <TextBox.Style>
        <Style TargetType="TextBox">
            <Setter Property="IsEnabled" Value="True"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Customer.CustomerID}" Value="0" >
                    <Setter Property="IsEnabled" Value="False"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
<TextBox>

请注意,DataTrigger的setter所设置的值只能覆盖样式setter中所设置的值。如果您直接设置值,则触发器将无法起作用。
原因是依赖属性值优先级
DataTrigger仅适用于相等条件,因此如果您需要检查负数,那么请使用第二个选项 - 值转换器

有没有可能将这个通用化,因为我将在多个屏幕上使用它,有时它是customerID,而其他时候可能是employeeID。像templateBinding这样的东西。 - Manvinder
好的,您可以尝试使用许多不同的触发器来创建样式。然后绑定将仅适用于其中一个触发器。另一种方法是创建 ValueConverter,该转换器将接受整个实体(客户或员工),并在代码中使用适当的属性返回 IsEnabled 的值。 - Pavel Voronin
谢谢,我非常理解值转换器的概念,但我也想使用数据触发器来做同样的事情。从您的评论中我所能理解的是,我需要为不同的屏幕创建不同的触发器,并使用它们的属性。我的理解是正确的吗?我们没有一些通用的方法来做这个吗? - Manvinder
1
是的,你理解得很正确,但我建议你检查一下性能:绑定不喜欢无法解析的路径。我现在不能告诉你通用的方法。似乎这是不可能的。我建议你考虑可测试性。你想把一部分业务逻辑放到视图中。虽然这主要是一个表示逻辑,但我更喜欢在我的ViewModel中使用“IsEnabled”属性。我以后可以引入更复杂的逻辑,这些逻辑无法通过DataTriggers表达。 - Pavel Voronin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接