【问题标题】:Exposed Bindable Property not binding correctly暴露的可绑定属性未正确绑定
【发布时间】:2021-01-28 20:48:27
【问题描述】:

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

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

xaml:

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

【问题讨论】:

  • 它实际上更破坏了它,但那是因为它在页面内部使用,其中绑定上下文设置为视图模型。像这样&lt;controls:CheckboxWithTextControl x:Name="name" Text="text" IsChecked="{Binding property}"/&gt;`

标签: c# xamarin xamarin.forms binding bindableproperty


【解决方案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">

【讨论】:

    【解决方案2】:

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

    我测试你的代码,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));
            }
        }
    }
    

    【讨论】:

    • 据我所知,您所做的唯一更改是对网格中事物的放置方式,这不是我想要实现的外观......我确实明白绑定只会失败当我点击复选框本身时,当我触摸它所做的一切时
    • @BananaSupreme 根据您之前的描述,您没有指出具体问题,所以我只能尝试使用您的代码来恢复您的问题。但很高兴你解决了你的问题。
    猜你喜欢
    • 1970-01-01
    • 2014-09-06
    • 1970-01-01
    • 2011-04-21
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多