【问题标题】:Struggling With MVVM与 MVVM 斗争
【发布时间】:2018-05-23 15:32:55
【问题描述】:

我有一个名为 osmAppBarButton 的类,它继承自 AppBarButton (UWP),我向其中添加了一个名为 ButtonState 的依赖项属性。 (枚举 Normal、Dim、Bright、Flash)

我的所有 osmAppBarButtons 都使用了一个 Style,它使用 DataTriggerBehavior 检查 ButtonState 并选择适当的 VisualState。

我对自己很满意,因为 DP 和 VisualStateManager 对我来说都是新的。然后我遇到了一个问题..

如何在不破坏 MVVM 的情况下从 ViewModel 更改 osmAppBarButton 的 ButtonState?我曾想过在我的视图中为每个按钮的 ButtonState 设置一个 VM 属性,但这意味着 VM 会对视图有所了解。

我认为答案可能在于附加行为,但我还没有找到适合的示例。

有什么想法吗?

【问题讨论】:

    标签: xaml mvvm uwp


    【解决方案1】:

    从视图模型属性获取值到依赖属性的方法是使用Binding。当然不是依附行为;我相信您可以找到一些方法来通过附加的行为来做到这一点,但只需使用Binding

    `viewmodel 必须实现 INotifyPropertyChanged,并且它必须是 appbar 按钮所在的视图的 DataContext,并且您不能通过将 DataContext 绑定到 appbar 按钮的某个父级中的某个随机内容而自取其辱。

    给视图模型一个公共属性,当它的值改变时会引发 PropertyChanged。绑定到该属性。

    ButtonState 这样具有 Normal、Dim、Bright、Flash 值的枚举并不是视图模型在“正确”的 MVVM 实现中应该注意的事情。这实际上也不是一个愚蠢的观点。我建议让视图模型通过以自己的术语表达视图模型状态的属性来公开其状态(如果我知道你在这里做什么,我可以给你一个例子)。也许视图模型的状态可以是正常、忙碌、错误、等待——这些可能映射到各种 ButtonState 值。 “错误”是视图模型的状态。 “Flash”是视图可能选择将给定视图模型状态传达给用户的众多方式之一。

    如果视图模型使用一个或多个类型不是ButtonState 的属性来表达相关状态,您将编写一个转换器——也许是一个多转换器——将所有这些转换为一个ButtonState 值。

    但是,如果您的学习程序在视图模型中使用ButtonState,这不会是世界末日,而且会更简单。所以把它绑定到这个:

    private ButtonState _fooBarButtonState = ButtonState.ItsComplicated;
    public ButtonState FooBarButtonState {
        get { return _fooBarButtonState; }
        set {
            if (value != _fooBarButtonState) {
                _fooBarButtonState = value;
                OnPropertyChanged(nameof(FooBarButtonState));
            }
        }
    }
    

    XAML:

    <local:osmAppBarButton 
        ButtonState="{Binding FooBarButtonState}" 
        />
    

    但是,如果您愿意接受我的建议,在视图模型中使用不同的状态枚举,那么转换器编写起来非常简单。让我知道你是否遇到了障碍,但如果你有一个依赖属性和视图状态工作,你会明白的。

    【讨论】:

      猜你喜欢
      • 2020-09-18
      • 2013-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-30
      • 2014-10-04
      • 2019-08-10
      相关资源
      最近更新 更多