【问题标题】:How to change a WPF control's visibility from ViewModel如何从 ViewModel 更改 WPF 控件的可见性
【发布时间】:2010-11-27 19:21:37
【问题描述】:

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

【问题讨论】:

    标签: wpf mvvm prism


    【解决方案1】:

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

    <Style.Resources>
         <BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter" />
    </Style.Resources>
    
    <Image Visibility="{Binding Path=ShowImage, 
                        Converter={StaticResource booleanToVisibilityConverter}}"/>
    

    希望这会有所帮助。

    埃齐奎尔·贾迪布

    【讨论】:

    • 不知何故这对我不起作用。我在 Usercontrol.Resources 部分声明了转换器并使用了您在评论中解释的绑定。
    【解决方案2】:

    虽然添加布尔属性并使用值转换器可以工作,但我建议向您的 ViewModel 添加 Visibility 类型的属性,例如

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

    这种方法的优点是您不需要为要以可视方式表达的每个属性编写转换器(例如,对于在低于 10 时将标签变为红色的库存水平,您可以有一个您使用一次的转换器或仅从您的 VM 公开 StockLabelBrush 属性)

    【讨论】:

    • 虽然这个答案很优雅,但它存在问题。如果程序更改shouldShowImage,则该更改不会发送到视图。
    • 确实如此,但有几种方法可以解决此问题。您可以处理来自shouldShowImagePropertyChanged 事件并引发新的PropertyChanged 事件,或者只允许通过引发两个属性的事件的包装器属性访问shouldShowImage
    • 我可以看到这里发生了两件事,(i) 我决定某事是真还是假(这似乎适合 VM 执行)和 (ii) 我采用该布尔值并决定是否某些控件应该可见或不可见(这似乎适合视图。我认为在这里使用转换器对于保持 V/VM 边界清洁而言是理想的。
    • @PeteH,ViewModel 和 Model 之间的区别在于 ViewModel 关注视图中显示的内容。如果在 ViewModel 中没有该逻辑,您就只有一个模型。此外,如果逻辑在 VM 中,当布尔值发生变化时,很容易测试视图上的元素是否可见。
    【解决方案3】:

    对于遇到此问题的人来说,有一个简单的解决方案。

    在您的视图模型中,像这样创建一个“可见性”属性:

    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

    【讨论】:

      猜你喜欢
      • 2016-01-06
      • 1970-01-01
      • 2023-04-09
      • 2011-10-12
      • 2018-10-03
      • 2015-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多