如何更改WPF控件';视图模型的可见性

如何更改WPF控件';视图模型的可见性,wpf,mvvm,prism,Wpf,Mvvm,Prism,我有一个WPF应用程序,试图实现MVVM模式和Prism 2。我有一个Usercontrol,它订阅了从另一个Usercontrol触发的事件。我想切换订阅控件中少数子元素的可见性。即使我能够成功地将数据绑定到某些元素,事件也会被正确触发。如何将可见性或任何样式属性绑定到ViewModel并动态更改它们。您可以在ViewModel中拥有一个布尔属性,并将该属性绑定到控件的可见性属性。由于您将指定一个布尔值,而Visibility属性需要一个Visibility枚举值,因此必须使用转换器进行转换

我有一个WPF应用程序,试图实现MVVM模式和Prism 2。我有一个Usercontrol,它订阅了从另一个Usercontrol触发的事件。我想切换订阅控件中少数子元素的可见性。即使我能够成功地将数据绑定到某些元素,事件也会被正确触发。如何将可见性或任何样式属性绑定到ViewModel并动态更改它们。

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

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

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

希望这有帮助


Ezequiel Jadib

尽管添加布尔属性和使用值转换器是可行的,但我建议您在ViewModel中添加Visibility类型的属性,例如

public Visibility ImageVisibility
{
    get { return shouldShowImage ? Visibility.Visible : Visibility.Collapsed }
}

此方法的优点是,您不需要为要以可视化方式表示的每个属性编写转换器(例如,对于当标签降至10以下时变为红色的库存级别,您可以使用一次转换器,或者仅从VM中公开StockLabelBrush属性)对于遇到此问题的人,有一个简单的解决方案

在视图模型中,创建“可见性”属性,如下所示:

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.Collapsed
Visibility.Visibility

不知怎的,这对我不起作用。我在Usercontrol.Resources部分声明了converter,并使用了绑定,正如您在注释中所解释的。虽然这个答案很优雅,但它有一个问题。如果程序发生更改
shouldShowImage
,则该更改不会发送到视图。确实如此,但有几种方法可以处理该问题。您可以从
shouldShowImage
处理
PropertyChanged
事件并引发新的
PropertyChanged
事件,或者只允许通过为两个属性引发事件的包装器属性访问
shouldShowImage
我决定某件事是真是假(对于VM来说这似乎是合适的),并且(ii)我取那个布尔值并决定某个控件是否应该可见(这似乎适用于视图。我认为在这里使用转换器对于保持V/VM边界干净来说是理想的。@PeteH,ViewModel和模型之间的区别在于ViewModel关注视图中显示的内容。如果ViewModel中没有这种逻辑,您就只有一个模型。而且,很容易如果逻辑在VM中,则当布尔值更改时,视图上的元素变得可见。