【问题标题】:My StateButton state is not updating my view我的 StateButton 状态没有更新我的视图
【发布时间】:2019-09-04 03:10:09
【问题描述】:

我正在尝试使用 Xamarin.CustomControls 中的 StateButtons

我有 2 个状态按钮,我希望它们以二分法的方式工作。

我的视图模型是这样的:

        private bool _btn1Active { get; set; }

        public bool Btn1Active
        {
            get
            {
                return _btn1Active;
            }
            set
            {
                if(_btn1Active != value)
                {
                    _btn1Active = value;

                    NotifyPropertyChanged("Btn1Active");
                }
            }
        }

        private bool _btn2Active { get; set; }

        public bool Btn2Active
        {
            get
            {
                return _btn2Active;
            }
            set
            {
                if(_btn2Active != value)
                {
                    _btn2Active = value;

                    NotifyPropertyChanged("Btn2Active");
                }
            }
        }

我已经绑定了这样的状态按钮:

Btn1.SetBinding(StateButton.IsPressedProperty, "Btn1Active");
Btn2.SetBinding(StateButton.IsPressedProperty, "Btn2Active");

而我的 button_clicked 处理程序是:


private void Btn_Clicked(object sender, EventArgs e)
        {
            var myViewModel = BindingContext as BtnsViewModel;

            myViewModel.Btn1Active= !myViewModel.Btn1Active;
            myViewModel.Btn2Active= !myViewModel.Btn2Active;

        }

我已经调试了很长时间,我看到每个属性都得到了正确的通知和更改,但是视图没有更新。

【问题讨论】:

    标签: android ios xamarin xamarin.forms


    【解决方案1】:

    我创建了一个演示来测试您的代码,它可以正常工作。 主要代码如下:

      public class TestModel2: INotifyPropertyChanged
    {
        public TestModel2()
        {
            Btn1Active = false;
            Btn2Active = false;
        }
    
        private bool _btn1Active;
        public bool Btn1Active
        {
            set { SetProperty(ref _btn1Active, value); }
            get { return _btn1Active; }
        }
    
        private bool _btn2Active;
        public bool Btn2Active
        {
            set { SetProperty(ref _btn2Active, value); }
            get { return _btn2Active; }
        }
    
    
    
        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;
    }
    

    MyPage.xaml

    <statebutton:StateButton Text="Rotate1" x:Name="Btn1" IsPressed="{Binding Btn1Active}"   RotateImages="true" ActiveTextColor="White" ActiveBackgroundColor="Teal" TextColor="Black" BackgroundColor="Green" ActiveBorderColor="Black" LeftImage="arrowRight" ActiveLeftImage="arrowDown" RightImage="arrowRight" HeightRequest="60"  />
    <statebutton:StateButton Text="Rotate2" x:Name="Btn2" IsPressed="{Binding Btn2Active}"   RotateImages="true" ActiveTextColor="White" ActiveBackgroundColor="Teal" TextColor="Black" BackgroundColor="Green" ActiveBorderColor="Black" LeftImage="arrowRight" ActiveLeftImage="arrowDown" RightImage="arrowRight" HeightRequest="60"  />
    
    <statebutton:StateButton Text="click(StateButton)" HeightRequest="60"  Clicked="StateButton_Clicked"/>
    <Button  Text="click(Button)" HeightRequest="60" Clicked="Button_Clicked"/>
    

    MyPage.xaml.cs

    public partial class MyPage : ContentPage
    {
        TestModel2 myViewModel;
    
        public MyPage ()
        {
            InitializeComponent ();
            myViewModel = new TestModel2();
            BindingContext = myViewModel;           
        }
    
        private void Button_Clicked(object sender, EventArgs e)
        {
            myViewModel.Btn1Active = !myViewModel.Btn1Active;
            myViewModel.Btn2Active = !myViewModel.Btn2Active;
        }
        private void StateButton_Clicked(object sender, EventArgs e)
        {
            myViewModel.Btn1Active = !myViewModel.Btn1Active;
            myViewModel.Btn2Active = !myViewModel.Btn2Active;
        }
    } 
    

    更新

    我为StateButtons 添加了一个点击事件,它也可以正常工作。 您可以查看更新后的代码。

    结果是:

    注意:

    1.修改如下代码:

    private bool _btn1Active { get; set; }
    private bool _btn2Active { get; set; }
    

    到:

     private bool _btn1Active;
     private bool _btn2Active;
    

    2。你使用的绑定方式不正确,你可以试试这个:

    Btn1.SetBinding(StateButton.IsPressedProperty, new Binding("Btn1Active"));
    Btn2.SetBinding(StateButton.IsPressedProperty, new Binding("Btn2Active"));
    

    或绑定xaml

    <statebutton:StateButton Text="Rotate1" x:Name="Btn1" IsPressed="{Binding Btn1Active}"     />
    <statebutton:StateButton Text="Rotate2" x:Name="Btn2" IsPressed="{Binding Btn2Active}"     />
    

    3.注意你的BindingContext,你可以这样做:

    BtnsViewModel myViewModel;
    
    myViewModel = new BtnsViewModel();
    BindingContext = myViewModel;   
    

    更多细节可以查看我的演示代码。

    【讨论】:

    • 感谢您的回复。我的代码仍然无法正常工作。我认为这是 StateButtons 的 OnClicked 默认事件的问题,因为我使用一个额外的按钮测试了您的解决方案,该按钮可以管理行为并且它可以工作。我该怎么办?
    • 我添加了一个StateButton,它也可以正常工作。我已经更新了答案,你可以检查一下。
    【解决方案2】:

    在您的代码中,您的问题在于您的绑定。

    改成

    Btn1.SetBinding(StateButton.IsPressedProperty, new Binding("Btn1Active"));
    Btn2.SetBinding(StateButton.IsPressedProperty, new Binding("Btn2Active"));
    

    它应该可以工作。

    这是因为BtnsViewModel 不是按钮的Context,而是按钮所在的整个页面的Context

    一个建议,您的私有字段不需要是属性。我的意思是

    private bool _btn1Active { get; set; }
    private bool _btn2Active { get; set; }
    

    可以改成

    private bool _btn1Active;
    private bool _btn2Active;
    

    希望这会有所帮助。-

    【讨论】:

    • 非常感谢您的回复。当我对@Jessie Zhang 发表评论时,我的代码仍然无法正常工作。 :c
    猜你喜欢
    • 2019-03-28
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 2020-11-25
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    • 1970-01-01
    相关资源
    最近更新 更多