如何在加载页面时阻止触发开关上的切换事件?

Ala*_*an2 6 xamarin xamarin.forms

我的应用程序在 XAML 和后端 C# 代码中设置了一个开关,用于响应切换事件

<ViewCell x:Name="ss">
   <Switch x:Name="ssSwitch" Toggled="SsSwitch"   />
</ViewCell>

void SsSwitch(object sender, ToggledEventArgs e) {
    // Code to update database here
}
Run Code Online (Sandbox Code Playgroud)

当页面第一次加载时,我注意到 SwSwitch Toggled 事件被调用。

有什么方法可以阻止这种情况发生,因为没有理由在启动时更新数据库。

Sha*_*raj 4

选项 1:在 ViewModel 中使用属性设置器

如果您使用 MVVM - 解决此问题的最简单选项是使用属性设置器来检测值更新(如本链接所述)。但如果您想在此处调用可等待的方法,则此选项不起作用。此外,作为最佳实践,建议属性不应实现任何耗时的操作

bool _isToggled;
public bool IsToggled 
{ 
    get 
    {
        return _isToggled;
    } 
    set
    {
        _isToggled = value;
        // Add your update code here
    }
}
Run Code Online (Sandbox Code Playgroud)

选项 2:PropertyChanged在 ViewModel 中使用事件

下一个选项是订阅视图模型中的PropertyChanged事件并适当地处理它。这允许您定义异步处理程序,而异步处理程序又可以等待异步方法。

// Subscribe to event while constructing/assigning viewmodel
// viewCellVM.PropertyChanged += CategoryVM_PropertyChanged;

async void ViewCellVM_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if(e.PropertyName == nameof(ViewCellVM.IsToggled))
    {
        //call update code here
        //await DB.Update();
    }
}
Run Code Online (Sandbox Code Playgroud)

选项 3:OnAppearing()在 ViewCell 中覆盖

另一种选择是确保在 上更新Toggled后分配事件处理程序。因此,我做了一个快速实验来跟踪加载视图时调用方法的顺序。结果结果是:BindingContextViewCellHandle_ToggledOnBindingContextChangedOnAppearing

Handle_Toggled
OnBindingContextChanged
OnAppearing
Run Code Online (Sandbox Code Playgroud)

因此,在方法中分配处理程序OnAppearing(在 ViewCell 的代码隐藏中)也应该适用于这种情况:

//XAML:<Switch x:Name="switchBtn" IsToggled="{Binding IsToggled}" />
protected override void OnAppearing()
{
    base.OnAppearing();

    switchBtn.Toggled += Handle_Toggled;
    Debug.WriteLine("OnAppearing");
}

protected override void OnDisappearing()
{
    base.OnDisappearing();

    switchBtn.Toggled -= Handle_Toggled;
    Debug.WriteLine("OnDisappearing");
}
Run Code Online (Sandbox Code Playgroud)

Handle_Toggled仅当用户切换开关时才会调用此方法。