公开的可绑定属性未正确绑定

问题描述

我制作的自定义视图遇到了这个问题,该视图将复选框与文本连接起来,并允许您点击整个视图以勾选复选框。 但是当我从复选框绑定到公开的绑定时,它似乎对更改没有反应。 我显然不理解某些东西,并且希望这里的某个人可以看到我遗漏的那个明显的东西。 一个普通的复选框工作正常。

我查看了现场的几个解决方案并尝试了一些我发现的东西,但可惜没有骰子。

xml:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Celery.Controls.CheckBoxWithTextControl">
    <ContentView.Content>
        <Grid ColumnDeFinitions="*,48">
            <Grid.GestureRecognizers>
                <TapGestureRecognizer Tapped="OnTapped"/>
            </Grid.GestureRecognizers>
            <Label x:Name="displayedLabel"
                   HorizontalTextAlignment="Start"
                   VerticalTextAlignment="Center"/>
            <CheckBox x:Name="displayedCheckBox"
                      Grid.Column="1"
                      HorizontalOptions="Center"
                      VerticalOptions="Center">
                <visualstatemanager.VisualStateGroups>
                    <VisualStateGroupList>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="normal">
                                <VisualState.Setters>
                                    <Setter Property="Color" Value="{StaticResource TextColour}"/>
                                </VisualState.Setters>
                            </VisualState>
                            <VisualState x:Name="IsChecked">
                                <VisualState.Setters>
                                    <Setter Property="Color" Value="{StaticResource SecondryTextColor}"/>
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateGroupList>
                </visualstatemanager.VisualStateGroups>
            </CheckBox>
        </Grid>
    </ContentView.Content>
</ContentView>

cs

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace Celery.Controls
{
    [XamlCompilation(XamlCompilationoptions.Compile)]
    public partial class CheckBoxWithTextControl : ContentView
    {
        public static readonly BindableProperty TextProperty = 
            BindableProperty.Create("Text",typeof(string),typeof(CheckBoxWithTextControl),"Default",BindingMode.OneWay,propertyChanged: (bindable,oldValue,newValue) =>
                {
                    if (newValue != null && bindable is CheckBoxWithTextControl control)
                    {
                        control.displayedLabel.Text = (string)newValue;
                    }
                });


        public static readonly BindableProperty IsCheckedProperty =
            BindableProperty.Create("IsChecked",typeof(bool),false,BindingMode.TwoWay,propertyChanged: (BindableObject bindable,object oldValue,object newValue) =>
                {
                    if (newValue != null && bindable is CheckBoxWithTextControl control)
                    {
                        control.displayedCheckBox.IsChecked = (bool)newValue;
                    }
                });
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty,value); }
        }

        public bool IsChecked
        {
            get { return (bool)GetValue(IsCheckedProperty); }
            set { SetValue(IsCheckedProperty,value); }
        }

        public CheckBoxWithTextControl()
        {
            InitializeComponent();
        }

        private void OnTapped(object sender,EventArgs e)
        {
            IsChecked = !IsChecked;
        }
    }
}

编辑 1:我发现如果我点击复选框本身会中断,但点击屏幕的任何其他部分都可以。

解决方法

我更改了复选框,以便在更新时也更新公开的可绑定

private void OnCheckedChange(object sender,CheckedChangedEventArgs e)
        {
            if (IsChecked != e.Value) IsChecked = e.Value;
        }

复选框现在是

<CheckBox x:Name="DisplayedCheckbox"
                      Grid.Column="1"
                      HorizontalOptions="Center"
                      VerticalOptions="Center"
                      CheckedChanged="OnCheckedChange">
,

但是当我从复选框绑定到公开的绑定时,它似乎对更改没有反应。

我测试你的代码,Grid有一个问题,请修改你的代码如下:

 <ContentView.Content>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.GestureRecognizers>
            <TapGestureRecognizer Tapped="OnTapped" />
        </Grid.GestureRecognizers>
        <Label
            x:Name="DisplayedLabel"
            Grid.Column="0"
            HorizontalTextAlignment="End"
            VerticalTextAlignment="Center" />
        <CheckBox
            x:Name="DisplayedCheckbox"
            Grid.Column="1"
            HorizontalOptions="StartAndExpand"
            VerticalOptions="Center">
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroupList>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Normal">
                            <VisualState.Setters>
                                <Setter Property="Color" Value="Gray" />
                            </VisualState.Setters>
                        </VisualState>
                        <VisualState x:Name="IsChecked">
                            <VisualState.Setters>
                                <Setter Property="Color" Value="Red" />
                            </VisualState.Setters>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateGroupList>
            </VisualStateManager.VisualStateGroups>
        </CheckBox>
    </Grid>
</ContentView.Content>

然后你像这样使用这个自定义控件:

  <customcontrol:CheckboxWithTextControl IsChecked="{Binding property}" Text="text" />

您是否实施了 INotifyPropertyChanged 来更新属性值?

 public partial class Page1 : ContentPage,INotifyPropertyChanged
{
   
    private bool _property;
    public bool property
    {
        get { return _property; }
        set
        {
            _property = value;
            RaisePropertyChanged("property");
        }
    }
    public Page1()
    {
        InitializeComponent();           
        property = true;
        this.BindingContext = this;
    }

  
    public event PropertyChangedEventHandler PropertyChanged;

    
    public void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this,new PropertyChangedEventArgs(propertyName));
        }
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...