如何将不同类中的两个 Switch 控件绑定到同一个 bool 属性? [英] How to bind two Switch controls in separate classes to the same bool property?

查看:31
本文介绍了如何将不同类中的两个 Switch 控件绑定到同一个 bool 属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个首选项中心,它需要为两个具有相同布尔值/切换值的独立 Switch 切换同步更新.我在 C# 中使用 Xamarin Forms.我有一个 ViewModel.cs 文件,例如

I am making a preference center that needs to sync updates for two separate Switch toggles with the same boolean/ toggle value. I am using Xamarin Forms with C#. I have a ViewModel.cs file such as

namespace XamarinDemoApp
public class MyViewModel : INotifyPropertyChanged
{
    private bool swithOne;
    public bool SwithOne
    {
        set
        {
            if (swithOne != value)
            {
                swithOne = value;
                OnPropertyChanged("SwithOne");
            }
        }
        get
        {
            return swithOne;
        }
    }

public MyViewModel()
    {
        SwithOne = true; // assign a value for `SwithOne `
    }

    bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (Object.Equals(storage, value))
            return false;

        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;

    }
}

然后我的 AllowSaleToggleTab.xaml.cs 看起来像

namespace XamarinDemoApp
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class AllowSaleToggleTab : ContentPage
{
    MyViewModel myViewModel;
    public AllowSaleToggleTab()
    {
        InitializeComponent();
        myViewModel = new MyViewModel();
        BindingContext = myViewModel;
    }
}
}

另一个切换选项卡是 PC.xaml.cs

namespace XamarinDemoApp
{
[XamlCompilation(XamlCompilationOptions.Compile)]

public partial class PC : ContentPage
{
    MyViewModel myViewModel;

    public PC()
    {
        InitializeComponent();
        Console.WriteLine("PC Initialized");
        myViewModel = new MyViewModel();
        BindingContext = myViewModel;
    }
}
}

最后,我随附的 PC.xamlAllowSaleToggleTab.xaml 文件都有元素

Finally, both my accompanying PC.xaml and AllowSaleToggleTab.xaml files have the elements

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:xamarindemoapp="clr-namespace:XamarinDemoApp" x:DataType="xamarindemoapp:MyViewModel"
             x:Class="XamarinDemoApp.AllowSaleToggleTab">
    <Switch x:Name="ToggleSwitch1"  IsToggled="{Binding SwithOne}"/>

但它们仍然不同步.谁能指出我做错了什么?谢谢

Yet they still don't sync. Can anyone point out what I'm doing wrong? Thank you

推荐答案

我不知道你的代码是如何使用的,但是有几种方法可以实现这一点.

I don't know how your code is used,but there are several methods to achieve this.

例如,您可以在导航或使用 Xamarin.Forms MessagingCenter 在两个页面之间发送数据消息.

For example,you can pass the data between two different Pages when navigating or use Xamarin.Forms MessagingCenter to send the data message between the two pages.

你可以参考下面的代码(我结合了上面的两种方法):

You can refer to the following code(I combined the two methods above):

TestPage1.xaml

<ContentPage.Content>
    <StackLayout>
        <Switch x:Name="toggleSwitch1" IsToggled="{Binding SwithOne}"   HorizontalOptions="Center">
        </Switch>
        <Button  Text="navigate to Page2"  Clicked="Button_Clicked"/>
    </StackLayout>
</ContentPage.Content>

TestPage1.xaml.cs

public partial class TestPage1 : ContentPage
{
     MyViewModel myViewModel;
    public TestPage1()
    {
        InitializeComponent();

        myViewModel = new MyViewModel();
        BindingContext = myViewModel;
    }
    private async void Button_Clicked(object sender, EventArgs e)
    {
        await Navigation.PushAsync( new TestPage2(myViewModel.SwithOne));//myViewModel.SwithOne
    }
}

MyViewModel.cs

public  class MyViewModel: INotifyPropertyChanged
{       
    private  bool _swithOne { get; set; }
    public  bool SwithOne
    {
        set
        {
            if (_swithOne != value)
            {
                _swithOne = value;
                OnPropertyChanged("SwithOne");

            }
        }
        get
        {
            return _swithOne;
        }
    }

    public MyViewModel()
    {
        SwithOne = true;

        MessagingCenter.Subscribe<object, object>(this, "PassDataToOne", (sender, args) =>
        {
            bool value = (bool)args;

            if (value!= SwithOne) {

                SwithOne = value;
            }
          
        });
    }

    bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (Object.Equals(storage, value))
            return false;

        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    protected   void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;

}

TestPage2.xaml

<ContentPage.Content>
    <StackLayout>
        <Switch x:Name="toggleSwitch2" IsToggled="{Binding SwithTwo}"   HorizontalOptions="Center" />

        <Button  Text="Navigate To  Page 1" Clicked="Button_Clicked"/>
    </StackLayout>
</ContentPage.Content>

TestPage2.xaml.cs

public partial class TestPage2 : ContentPage
{
    MyViewModel2 myViewModel;

    public TestPage2(bool isToggled)
    {
        InitializeComponent();

         myViewModel = new MyViewModel2(isToggled);

        BindingContext = myViewModel;
    }

    private async void Button_Clicked(object sender, EventArgs e)
    {
        await Navigation.PopAsync();
    }
}

MyViewModel2.cs

public class MyViewModel2: INotifyPropertyChanged
{
    private bool _swithTwo;
    public bool SwithTwo
    {
        set
        {
            if (_swithTwo != value)
            {
                _swithTwo = value;
                OnPropertyChanged("SwithTwo");

                MessagingCenter.Send<object, object>(this, "PassDataToOne", _swithTwo);

            }
        }
        get
        {
            return _swithTwo;
        }
    }

    public MyViewModel2( bool isToggled)
    {
        SwithTwo = isToggled;
    }


    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

注意:

1.我为两个页面使用了两个不同的ViewModel(TestPage1TestPage2),TestPage1的ViewModel是MyViewModel,TestPage1的ViewModel是MyViewModel2.

1.I Used two different ViewModels for the two pages(TestPage1 and TestPage2), TestPage1's ViewModel is MyViewModel, and TestPage1's ViewModel is MyViewModel2.

2.在TestPage1中改变Switch的状态后,我们可以在MyViewModel.cs中传递值SwithOnecode> 到 TestPage2 由构造函数:

2.After changing the status of Switch in TestPage1,we can pass the value SwithOne in MyViewModel.cs to TestPage2 by the Constructor:

    private async void Button_Clicked(object sender, EventArgs e)
    {
        await Navigation.PushAsync( new TestPage2(myViewModel.SwithOne));//myViewModel.SwithOne
    }

3.如果我们改变TestPage2SwithTwo的值,我们可以使用MessagingCenter将值发送到TestPage1:

3.If we change the value of SwithTwo in TestPage2,we can use MessagingCenter to send the value to TestPage1:

   public class MyViewModel2: INotifyPropertyChanged
{
    private bool _swithTwo;
    public bool SwithTwo
    {
        set
        {
            if (_swithTwo != value)
            {
                _swithTwo = value;
                OnPropertyChanged("SwithTwo");

                MessagingCenter.Send<object, object>(this, "PassDataToOne", _swithTwo);

            }
        }
        get
        {
            return _swithTwo;
        }
    }
// other code
}

这篇关于如何将不同类中的两个 Switch 控件绑定到同一个 bool 属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆