Привязываемая собственность форм Xamarin с OneWay не работает - PullRequest
1 голос
/ 23 января 2020

Я хочу привязать CustomLabel к виртуальной машине, создав новое свойство привязки.

В режиме OneWay первые данные виртуальной машины правильно изменили свойство CustomLabel. но это не сработало во второй раз.

Хотя событие VM произошло, свойство Bindable CustomView не запустило событие PropertyChanged.

Хотя оно работает должным образом в режиме TwoWay.

Я уже два дня тестирую и ищу причину, но не могу найти ее.

Кто-нибудь подскажет, как это сделать?

// HomeViewModel.cs
public class HomeViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string _customName = "-";
    
    public string CustomName
    {
        get
        {
            Debug.WriteLine("Get_CustomName");
            return _customName;
        }
        set
        {
            if (value != _customName)
            {
                Debug.WriteLine("Set_CustomName");
                _customName = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CustomName)));
            }
        }
    }
}

// MainPage.cs
public partial class MainPage : ContentPage
{
    HomeViewModel Vm = new HomeViewModel();

    public MainPage()
    {
        InitializeComponent();
        BindingContext = Vm;
    }

    void ButtonTrue_Clicked(object sender, EventArgs e)
    {
        Vm.CustomName = "True";
    }

    void ButtonFalse_Clicked(object sender, EventArgs e)
    {
        Vm.CustomName = "False";
    }
}

<!-- MainPage.xaml -->
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:Ex_Binding"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="Ex_Binding.MainPage">
    <StackLayout Padding="50,0" VerticalOptions="Center">
        <StackLayout Orientation="Horizontal" HorizontalOptions="Center">
            <Label Text="Custom Result : " />
            <local:CustomLabel x:Name="lbCustom" MyText="{Binding CustomName}" HorizontalOptions="Center" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Button Text="TRUE" BackgroundColor="LightBlue" HorizontalOptions="FillAndExpand" Clicked="ButtonTrue_Clicked" />
            <Button Text="FALSE" BackgroundColor="LightPink" HorizontalOptions="FillAndExpand" Clicked="ButtonFalse_Clicked" />
        </StackLayout>
    </StackLayout>
</ContentPage>

// CustomLabel.cs
public class CustomLabel : Label
{
    public static readonly BindableProperty MyTextProperty = BindableProperty.Create(nameof(MyText), typeof(string), typeof(CustomLabel), null, BindingMode.OneWay, propertyChanged: OnMyTextChanged);
    private static void OnMyTextChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var thisBindable = (CustomLabel)bindable;

        if (thisBindable != null)
        {
            thisBindable.MyText = (string)newValue;
        }
    }

    public string MyText
    {
        get => (string)GetValue(MyTextProperty);
        set
        {
            SetValue(MyTextProperty, value);
            Text = value;
        }
    }
}

1 Ответ

2 голосов
/ 23 января 2020

Причина:

 thisBindable.MyText = (string)newValue;

Поскольку вы устанавливаете значение MyText при изменении его значения. Поэтому он никогда не будет вызван в следующий раз (в TwoWay метод будет вызываться несколько раз).

Решение:

Вам следует установить Text в OnMyTextChanged напрямую.

 private static void OnMyTextChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var thisBindable = (CustomLabel)bindable;

        if (thisBindable != null)
        {
            thisBindable.Text = (string)newValue;
        }
    }

    public string MyText
    {
        get => (string)GetValue(MyTextProperty);
        set
        {
            SetValue(MyTextProperty, value);
            //Text = value;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...