xamarin - 如何在 Xamarin 中将视图模型绑定到 XAML 中的视图?
问题描述
我有一个非常基本的观点。
<ContentPage x:Class="ThetaRex.InvestmentManager.Merlin.Views.ScenarioSelectionPage"
Title="{Binding Title}"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns="http://xamarin.com/schemas/2014/forms">
<StackLayout>
<ListView ItemsSource="{Binding Items}"/>
</StackLayout>
<ContentPage/>
后面的代码也很简单:
namespace ThetaRex.InvestmentManager.Merlin.Views
{
using System.ComponentModel;
using ThetaRex.InvestmentManager.Merlin.ViewModels;
using Xamarin.Forms;
public partial class ScenarioSelectionPage : ContentPage
{
public ScenarioSelectionPage()
{
InitializeComponent();
this.BindingContext = this.ViewModel = new ScenarioSelectionViewModel();
}
public ScenarioSelectionViewModel ViewModel { get; set; }
protected override void OnAppearing()
{
base.OnAppearing();
ViewModel.LoadItemsCommand.Execute(null);
}
}
}
来自 WPF 和 UWP 中的纯 MVVM 环境,我想将视图绑定到 XAML 中的视图模型,而不是在后面的代码中使用this.Binding = ViewModel。我试过了:
<ContentPage x:Class="ThetaRex.InvestmentManager.Merlin.Views.ScenarioSelectionPage"
xmlns:controls="clr-namespace:ThetaRex.InvestmentManager.Merlin.Controls"
BindingContext="{Binding ViewModel}"
Title="{Binding Title}"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns="http://xamarin.com/schemas/2014/forms">
但它没有用。如何从 XAML 绑定到 ViewModel?
注意: 我知道我可以在 XAML 中从头开始创建视图模型,但它不使用与视图后面的代码相同的实例,所以这不是一个选项。
解决方案
如果我明白你想要什么,解决方案是像这样构建一个 ViewModelLocator:
- ViewModelLocalizator 类
public static class ViewModelLocalizator
{
public static readonly BindableProperty AutoWireViewModelProperty =
BindableProperty.CreateAttached("AutoWireViewModel", typeof(bool), typeof(ViewModelLocalizator), default(bool), propertyChanged: OnAutoWireViewModelChanged);
public static bool GetAutoWireViewModel(BindableObject bindable)
{
return (bool)bindable.GetValue(AutoWireViewModelProperty);
}
public static void SetAutoWireViewModel(BindableObject bindable, bool value)
{
bindable.SetValue(AutoWireViewModelProperty, value);
}
/// <summary>
/// VERIFY THE VIEW NAME AND ASSOCIATE IT WITH THE VIEW MODEL OF THE SAME NAME. REPLACING THE 'View' suffix WITH THE 'ViewModel'
/// </summary>
private static void OnAutoWireViewModelChanged(BindableObject bindable, object oldValue, object newValue)
{
if (!(bindable is Element view))
{
return;
}
var viewType = view.GetType();
var viewModelName = viewType.FullName.Replace(".Views.", ".ViewModels.").Replace("Page", "ViewModel");
var viewModelType = Type.GetType(viewModelName);
if (viewModelType == null) { return; }
var vmInstance = Activator.CreateInstance(viewModelType);
if (vmInstance != null)
{
view.BindingContext = vmInstance;
}
}
}
- 在您的视图上使用它
<ContentPage x:Class="YourProject.Views.YourTestPage"
Title="{Binding Title}"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:viewModelBase="clr-namespace:YourProject.ViewModels;assembly=YouProject"
viewModelBase:ViewModelLocalizator.AutoWireViewModel="true"
>
<StackLayout>
<ListView ItemsSource="{Binding Items}"/>
</StackLayout>
<ContentPage/>
推荐阅读
- css - 无法将页脚放在正确的位置 - 圣杯布局 - 引导网格
- java - 无法自动创建表
- c# - 为什么 Fody weaving 无法编织其他项目?
- django - 为什么 django 中的 Simple 标签不起作用?
- azure - 使用powershell,如何将消息从死信队列重新发送到常规队列?
- python - 合并两个 python pandas 数据框后,Jupyter 笔记本突然变得非常慢。它发生在我的 Mac 和窗口上
- erlang - MD5 未在 erlang 模块的模块信息中更新
- javascript - 剑道数字文本框最小值最大值不起作用
- c# - 如何将依赖项注入 App.xaml.cs?
- django - AWS Elastic Beanstalk 给出“无法将主机名“db”转换为地址”错误