0

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

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

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), typeof(CheckboxWithTextControl),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:我发现如果我点击复选框本身它会中断,但点击屏幕的任何其他部分都可以。

4

2 回答 2

0

我更改了复选框以在更新时更新暴露的可绑定对象

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">
于 2021-01-29T10:55:13.453 回答
-1

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

我测试了你的代码,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));
        }
    }
}
于 2021-01-29T02:02:33.300 回答