У меня есть страница 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;
}
}
@ Джейсон Я пробовал это, но это тоже не сработало. selectedDate и selectedDate1 в значении модели представления не обновляются.
Я даю вам обходной путь здесь.
Для 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");
}
Надеюсь, это сработает для вас.
DatePicker должен быть привязан к собственному свойству CardDate