【问题标题】:How to MVVM toggleswitch in UWP如何在 UWP 中使用 MVVM 切换开关
【发布时间】:2020-07-28 05:30:08
【问题描述】:

如何使用命令正确设置切换开关?我正在使用行为来使用 Toggled 事件启动命令。但是,当用户更改开关状态时我遇到了问题,但我的模型拒绝了它。我不知道如何正确编程,所以如果模型拒绝,视图会拒绝更新。

这是我的尝试(为清楚起见,跳过了 INotifyPropertyChanged 详细信息):

1。单向命令

class ToggleSwitchVm {
     public bool IsOn => Model.IsOn;
     public ICommand SwitchManipulated {get;}
}

当用户在 UI 中操作 ToggleSwitch 状态发生变化,但它与模型中的状态无关。在调用命令时,toggleswitch 也会忽略 PropertyChanged 事件:

async void SwitchManipulatedCommand(bool? state) {
    if(!Model.SetNewState(state.Value)) { // if failed to set state raise PropertyChanged to refresh view
        RaisePropertyChanged(nameof(IsOn)); // this call is ignored :(
    }
}

2。双向属性?

class ToggleSwitchVm { 
 
    private void ModelOnPropertyChanged(object sender, PropertyChangedArgs args){
       if(args.PropertyName == nameof(Model.IsOn)){
          IsOn = Model.IsOn;
       }

    }


    private bool _isOn;
    public bool IsOn 
    { 
        get => _isOn;
        set {
                if(SetValue(ref _isOn, value))
                {  // true if model was manipulated
                    // View set value, or model set value?
                    if(!Model.SetState(value))
                    {
                         RaisePropertyChanged(nameof(IsON)); // ignored by view
                    }
                }
            }
    }
}

这是一团糟,因为 Model 和 View 都设置了 IsOn 属性,无法知道是哪一个设置的。

【问题讨论】:

  • 快速浏览一下这个控件是什么,bool 属性是这样的。 “Model 和 View 都设置了 IsOn 属性并且无法知道哪个设置了它” 值得作为单独问题提出的问题,您需要显示有关它的详细信息。对于一个控件,谁来设置它并不重要:用户通过点击或虚拟机通过设置属性。
  • 所以您正在尝试制作一个可以绑定命令的自定义切换开关,对吧?
  • 我正在使用这种行为来添加命令:pastebin.com/xYvsbg3e

标签: c# mvvm uwp


【解决方案1】:

如何在 UWP 中使用 MVVM 切换开关

ToggleSwitch IsOnPropertyDependencyProperty,这意味着它可以使用双向模型绑定数据。而且您无需在命令方法中处理 IsOn 属性。请参考以下代码来实现该功能。

Xaml 代码

<Page.DataContext>
    <local:ViewModel />
</Page.DataContext>

<Grid>
    <ToggleSwitch
        Header="Toggle work"
        IsOn="{Binding IsOn, Mode=TwoWay}"
        OffContent="Do work"
        OnContent="Working"
        />
</Grid>

背后的代码

public class ViewModel: INotifyPropertyChanged
{
    private bool _isOn;
    public bool IsOn
    {
        get { return _isOn; }
        set { Set(ref _isOn, value); }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void Set<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
    {
        if (Equals(storage, value))
        {
            return;
        }

        storage = value;
        OnPropertyChanged(propertyName);
    }

    private void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-01
    • 1970-01-01
    • 2016-09-12
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多