.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");
}
Надеюсь, это сработает для вас.