.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;
    }
}

DatePicker должен быть привязан к собственному свойству CardDate

Jason 15.02.2023 23:54

@ Джейсон Я пробовал это, но это тоже не сработало. selectedDate и selectedDate1 в значении модели представления не обновляются.

Subhi 15.02.2023 23:57
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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 вы можете обратиться к этому официальному документу: Определите пользовательский интерфейс.

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

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

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

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