#c# #xaml #data-binding #maui
Вопрос:
Я пытаюсь передать модель представления в качестве аргумента страницы из XAML.
Вот базовая страница:
public abstract class BaseContentPage<T> : ContentPage where T : BaseVm
{
public BaseContentPage(T viewModel, string pageTitle)
{
BindingContext = ViewModel = viewModel;
Title = pageTitle;
}
protected T ViewModel { get; }
}
public abstract class BaseTabbedPage<T> : TabbedPage where T : BaseVm
{
public BaseTabbedPage(T viewModel, string pageTitle)
{
BindingContext = ViewModel = viewModel;
Title = pageTitle;
}
protected T ViewModel { get; }
}
Параметр содержит список устройств, определенных таким образом:
public partial class SettingsPage : BaseTabbedPage<SettingsVm>
{
public SettingsPage(SettingsVm vm) : base(vm, "Settings")
{
InitializeComponent();
}
}
public class SettingsVm : BaseVm
{
public DeviceListVm Devices { get; set; }
public SettingsVm(ILogger<SettingsVm> logger, MyConfig config) { }
}
public partial class DeviceListPage : BaseContentPage<DeviceListVm>
{
public DeviceListPage(DeviceListVm vm) : base(vm, "Devices")
{
InitializeComponent();
}
public DeviceListPage() : base(null, "Devices")
{
InitializeComponent();
}
}
Тогда самое сложное-это XAML:
<p:BaseTabbedPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:p="clr-namespace:MyProject.Pages"
xmlns:vm="clr-namespace:MyProject.ViewModels"
xmlns:vmd="clr-namespace:MyProject.ViewModels.Devices"
xmlns:local="clr-namespace:MyProject"
x:Class="MyProject.Pages.SettingsPage"
x:TypeArguments="vm:SettingsVm">
<NavigationPage Title="Schedule" IconImageSource="schedule.png">
<x:Arguments>
<p:DeviceListPage ViewModel="{Binding Devices}">
<!--x:Arguments>
<vmd:DeviceListVm>{Binding Devices}</vmd:DeviceListVm>
</x:Arguments-->
</p:DeviceListPage>
</x:Arguments>
</NavigationPage>
</p:BaseTabbedPage>
Мне не удается передавать устройства в качестве аргумента страницы списка устройств.
Я не хочу делать это программно, так как представления моделей предназначены для внедрения, за исключением этого случая, когда модель корневого представления содержит модель подвида для использования дочерней страницей.
Если я использую свойство ViewModel, я получаю следующую ошибку:
Ошибка XFC0009: Для «ViewModel» не найдено свойство, свойство привязки или событие или тип несоответствия между значением и свойством.
РЕДАКТИРОВАТЬ Я изменил базовый класс, чтобы объявить BindableProperty
:
public abstract class BaseContentPage<T> : ContentPage where T : BaseVm
{
public BaseContentPage(T viewModel, string pageTitle)
{
ViewModel = viewModel;
Title = pageTitle;
}
public T ViewModel
{
get => (T)GetValue(ViewModelProperty);
set => SetValue(ViewModelProperty, BindingContext = value);
}
public BindableProperty ViewModelProperty = BindableProperty.Create(nameof(ViewModel), typeof(T), typeof(BaseContentPage<T>));
}
public abstract class BaseTabbedPage<T> : TabbedPage where T : BaseVm
{
public BaseTabbedPage(T viewModel, string pageTitle)
{
ViewModel = viewModel;
Title = pageTitle;
}
public T ViewModel
{
get => (T)GetValue(ViewModelProperty);
set => SetValue(ViewModelProperty, BindingContext = value);
}
public BindableProperty ViewModelProperty = BindableProperty.Create(nameof(ViewModel), typeof(T), typeof(BaseTabbedPage<T>));
}
Затем я все равно получаю ту же ошибку XFC0009.
Комментарии:
1. Какой тип страницы списка устройств? Кажется, у вас
Protected T Viewmodel
есть, но если вы хотите использовать его так, как вы это делаете, вам следует сделатьBindableProperty
2. @JuanSturla Привязка свойства применяет значение к экземпляру по умолчанию. Можно ли передать привязку в качестве аргумента конструктора?
3. Является ли передача аргументов в XAML тем, о чем вы говорите?
4. @JessieZhang-MSFT
<p:DeviceListPage>
вызывает конструктор по умолчаниюDeviceListPage()
. Я бы хотел, чтобы он вызывал конструктор с моделью представленияDeviceListPage(DeviceListVm vm)
5. @JessieZhang-MSFT Не нашел синтаксис для использования с привязкой