.NET Maui Привязка представления содержимого к родительской ViewModel MVVM

У меня есть страница xaml, которая содержит два экземпляра одного и того же представления контента. Представление содержимого имеет средство выбора даты, которое должно обновлять значение в родительской модели представления (каждое представление содержимого должно обновлять другую переменную в модели представления). Я пытался сделать свойство bindiable, но оно не работает. Я установил для BindingMode значение TwoWay, но это не работает.

Проблема в том, что привязка не работает от представления содержимого к родительской модели представления через свойство привязки. Любой вклад очень ценится.

Ниже мой код:MainPage.xaml

      <?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            BackgroundColor="{DynamicResource PageBackgroundColor}"
             xmlns:picker="clr-namespace:TestSync.View"
             xmlns:viewmodel="clr-namespace:TestSync.ViewModel"
             x:DataType="viewmodel:TimeTrackerViewModel"
             x:Class="TestSync.MainPage">

    <VerticalStackLayout>

        <Label Text="{Binding SelectedDate}"/>

        <Label Text="{Binding SelectedDate1}"/>

        <picker:DateTimePickerContentView CardTitle="First DatePicker" CardDate="{Binding SelectedDate,Mode=TwoWay}" />
        
        <picker:DateTimePickerContentView CardTitle="Second DatePicker" CardDate="{Binding SelectedDate1,Mode=TwoWay}" />
 
    </VerticalStackLayout>

</ContentPage>

TimeTrackerViewModel.cs

      namespace TestSync.ViewModel
{
    public partial class TimeTrackerViewModel :ObservableObject
    {
        [ObservableProperty]
        public DateTime selectedDate;

        [ObservableProperty]
        public DateTime selectedDate1;
    }
}

DateTimePickerContentView.xaml

      <?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:viewmodel="clr-namespace:TestSync.View"
             x:DataType="viewmodel:DateTimePickerContentView"
             x:Class="TestSync.View.DateTimePickerContentView"
             >
    <VerticalStackLayout>

        <Label Text="{Binding CardTitle}"/>
        <DatePicker x:Name="myDate" Date="{Binding CardDate}" />

    </VerticalStackLayout>
</ContentView>

и DateTimePickerContetntView.xaml.cs

      
namespace TestSync.View;

public partial class DateTimePickerContentView : ContentView
{
    public static readonly BindableProperty CardTitleProperty = BindableProperty.Create(nameof(CardTitle), typeof(string), typeof(DateTimePickerContentView), string.Empty);

    public string CardTitle
    {
        get => (string)GetValue(DateTimePickerContentView.CardTitleProperty);
        set => SetValue(DateTimePickerContentView.CardTitleProperty, value);
    }


    public static readonly BindableProperty CardDateProperty = BindableProperty.Create(nameof(CardDate), typeof(DateTime), typeof(DateTimePickerContentView), defaultValue:DateTime.Parse("12/15/1992"),defaultBindingMode:BindingMode.TwoWay,propertyChanged:test);

    private static void test(BindableObject bindable, object oldValue, object newValue)
    {
        var mytest= bindable as DateTimePickerContentView;
        mytest.myDate.Date = (DateTime)newValue;
    }

    public DateTime CardDate
    {
        get => (DateTime)GetValue(DateTimePickerContentView.CardDateProperty);
        set => SetValue(DateTimePickerContentView.CardDateProperty, value);
    }
    public DateTimePickerContentView()
    {
        InitializeComponent();
        BindingContext = this;
    }
}

1 ответ

Я даю вам обходной путь здесь.

Для DateTimePickerContentView.xaml определите BindingContext

      <ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         ...
         x:Name="this">

    <VerticalStackLayout BindingContext="{x:Reference this}">
        <Label Text="{Binding CardTitle}"/>
        <DatePicker x:Name="myDate" Date="{Binding CardDate}" />
    </VerticalStackLayout>
</ContentView>

Итак, для DateTimePickerContentView.cs просто удалите эту строку

      ...
public DateTimePickerContentView()
{
    InitializeComponent();
    //BindingContext = this;
}

Для привязки данных в ContentView вы можете обратиться к этому официальному документу: Define the UI.

И если вы хотите установить значение по умолчанию, вы должны установить его в TimeTrackerViewModel, потому что конструктор TimeTrackerViewModel выполняется после того, как пользовательский элемент управления устанавливает значение по умолчанию. Затем он будет заменен, например, на 01.01.1900.

      public TimeTrackerViewModel()
{
    SelectedDate = DateTime.Parse("12/15/1992");
    SelectedDate1 = DateTime.Parse("12/15/1992");
}

Надеюсь, это сработает для вас.

Другие вопросы по тегам