如何从ViewModel更改WPF控件的可见性

14

我有一个使用WPF应用程序,尝试实现MVVM模式和Prism 2。我有一个用户控件,已经订阅了从另一个用户控件触发的事件。我想切换订阅控件中几个子元素的可见性。事件已经成功地被触发,我甚至能够成功地将数据绑定到一些元素。如何使用ViewModel绑定Visibility或任何样式属性,并在运行时动态更改它们。

3个回答

27

您可以在ViewModel中拥有一个布尔属性,并将该属性绑定到控件的可见性属性。由于您将分配一个布尔值,而可见性属性期望一个可见性枚举值,因此您将需要使用BooleanToVisibilityConverter转换器来进行转换。

<Style.Resources>
     <BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter" />
</Style.Resources>

<Image Visibility="{Binding Path=ShowImage, 
                    Converter={StaticResource booleanToVisibilityConverter}}"/>

希望这能有所帮助。
Ezequiel Jadib

不知何故,这对我没有起作用。我在Usercontrol.Resources部分声明了converter,并按照您在评论中解释的方式使用了绑定。 - Raj

10

虽然添加布尔属性并使用值转换器可以实现此功能,但我建议向您的ViewModel添加一个类型为Visibility的属性,例如:

public Visibility ImageVisibility
{
    get { return shouldShowImage ? Visibility.Visible : Visibility.Collapsed }
}
这种方法的优点在于,您无需为想要以视觉方式表达的每个属性编写转换器(例如,对于当库存水平低于10时将标签变红的情况,您可以只使用一次转换器或者从VM公开一个StockLabelBrush属性)。

虽然这个答案很优雅,但它存在一个问题。如果程序更改了 shouldShowImage,那么这个变化不会被发送到视图。 - James
2
这是正确的,但是有几种方法可以处理这个问题。您可以处理shouldShowImagePropertyChanged 事件并引发新的 PropertyChanged 事件,或者仅通过包装器属性访问shouldShowImage,为两个属性都引发事件。 - Darren
1
我可以看到这里有两件事情正在进行,(i) 我决定某些东西是真还是假(这似乎适合由VM来完成),以及 (ii) 我拿到布尔值并决定某些控件是否可见(这似乎适合由View来完成)。我认为在这里使用转换器是保持V/VM边界清晰的理想选择。 - PeteH
@PeteH,ViewModel和Model的区别在于ViewModel关注于视图中显示的内容。如果没有ViewModel中的逻辑,你只有一个Model。此外,如果逻辑在VM中,测试视图上的元素何时变得可见就非常容易了。 - Darren
这很糟糕,因为如果您将代码移植到不同的 .Net 技术(例如 MAUI),它将无法工作,而布尔方法更具可移植性。 - Piotr Golacki

2
您遇到此问题时,有一个简单的解决方案。
在您的视图模型中,创建一个名为“Visibility”(可见性)的属性,如下所示:
public Visibility ShowModifyButtons
    {
        get { return (Visibility)GetValue(ShowModifyButtonsProperty); }
        set { SetValue(ShowModifyButtonsProperty, value); }
    }

public static readonly DependencyProperty ShowModifyButtonsProperty =
        DependencyProperty.Register("ShowModifyButtons", typeof(Visibility), typeof(FileMatchViewModel),
        new UIPropertyMetadata(Visibility.Collapsed));

在您的XAML中,可以像这样进行绑定:

 <Button Focusable="False" Content="Save" Width="100" Margin="10" Visibility="{Binding ShowModifyButtons}"/>

现在,从您的视图模型中,您可以根据需要将ShowModifyButtons设置为Visibility.CollapsedVisibility.Visible

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