簡體   English   中英

如何在 UWP 中切換 MVVM

[英]How to MVVM toggleswitch in UWP

如何使用命令正確設置切換開關? 我正在使用行為來使用 Toggled 事件啟動命令。 但是,當用戶更改開關的 state 時,我遇到了問題,但我的 model 拒絕了它。 我不知道如何正確編程,所以如果被 model 拒絕,視圖將拒絕更新。

這是我的嘗試(為清楚起見,跳過了 INotifyPropertyChanged 的詳細信息):

1.單向命令

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

當用戶在 UI 更改中操作 ToggleSwitch state 時,它與 model 中的 state 無關。並且 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 屬性,並且無法知道是哪一個設置了它。

如何在 UWP 中切換 MVVM

ToggleSwitch IsOnPropertyDependencyProperty ,這意味着它可以使用兩種方式綁定數據 model。並且您無需在命令方法中處理 IsOn proprty。 請參考以下代碼來實現該功能。

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));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM