How to correctly setup toggleswitch with command? I am using behavior to launch command using Toggled event. However I have problem when user changed state of switch, but my model rejects it. I do not know how to correctly program it, so view rejects update if it was rejected by model.
Here are my attempts to do it (INotifyPropertyChanged details skipped for clarity):
class ToggleSwitchVm {
public bool IsOn => Model.IsOn;
public ICommand SwitchManipulated {get;}
}
When user manipulates ToggleSwitch state in UI changes, but it is not related to state in model. Also toggleswitch ignores PropertyChanged events, while it is calling command:
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 :(
}
}
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
}
}
}
}
}
This is a mess, because both Model and View set IsOn property and there is no way to know which one set it.
How to MVVM toggleswitch in UWP
The ToggleSwitch IsOnProperty
is DependencyProperty
, that means it could use to bind data with two way model. And you have no need to process the IsOn proprty in command method. Please refer the following code to implement the feature.
Xaml Code
<Page.DataContext>
<local:ViewModel />
</Page.DataContext>
<Grid>
<ToggleSwitch
Header="Toggle work"
IsOn="{Binding IsOn, Mode=TwoWay}"
OffContent="Do work"
OnContent="Working"
/>
</Grid>
Code behind
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));
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.