Xamarin MVVM模式下XAML如何访问视图代码隐藏类成员
问题解答
首先明确:使用ViewModel不会断开XAML与代码隐藏文件的关联。你现在能正常绑定ViewModel属性,只是因为你将页面的BindingContext赋值为了ViewModel实例,默认无指定源的绑定会从BindingContext中查找属性,并非XAML无法访问代码隐藏类的成员。
你目前无法访问ACCESS_ME有两个直接原因:
ACCESS_ME是公共字段,XAML绑定系统仅支持识别公共属性,无法识别字段- 页面默认绑定上下文是ViewModel实例,直接写
{Binding ACCESS_ME}会去ViewModel中查找对应成员,自然找不到目标
具体实现方法
方法1:通过x:Reference引用页面实例绑定(最简便)
- 首先修改代码隐藏类,将公共字段改为公共属性:
namespace xxxProject { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class xxxView: ContentPage { // 改为公共属性,保证绑定系统可识别 public string ACCESS_ME { get; } = "hello"; public xxxView() { InitializeComponent(); BindingContext = new xxxViewModel(); } } }
- 修改XAML代码,给当前页面添加
x:Name标记,绑定代码隐藏类属性时明确指定绑定源为当前页面。注意你开启了编译绑定,需要给绑定代码隐藏属性的控件单独指定x:DataType,避免编译报错:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="xxxProject.xxxView" x:DataType="xxxViewModel" xmlns:viewmodels="clr-xxxProject.ViewModels" xmlns:local="clr-namespace:xxxProject" x:Name="CurrentPage" > <ContentPage.Content> <StackLayout> <!-- 原有ViewModel属性绑定不需要修改,可正常工作 --> <Label Text="{Binding myProperty}" /> <!-- 绑定代码隐藏类属性,明确指定源为当前页面 --> <Label Text="{Binding Source={x:Reference CurrentPage}, Path=ACCESS_ME}" x:DataType="local:xxxView"/> </StackLayout> </ContentPage.Content> </ContentPage>
方法2:通过相对源查找页面实例,无需设置x:Name
如果不想给页面添加x:Name标记,可以直接通过相对源绑定查找当前页面实例,仅需要修改对应控件的绑定写法即可,代码隐藏类的修改和方法1一致:
<Label Text="{Binding Source={RelativeSource AncestorType={x:Type local:xxxView}}, Path=ACCESS_ME}" x:DataType="local:xxxView" xmlns:local="clr-namespace:xxxProject"/>
补充说明
如果不需要通过绑定访问,只是要在代码隐藏逻辑中操作XAML内的控件,只需要给对应控件添加x:Name标记,就可以在代码隐藏类中直接通过名称访问控件实例,这个机制和你是否使用ViewModel没有任何关联。
遵循MVVM模式时,业务逻辑、业务状态相关的属性建议放在ViewModel中,纯视图层、和业务逻辑无关的属性放在代码隐藏类中是完全合理的,不会违反MVVM原则。
内容的提问来源于stack exchange,提问作者Sami.C
相关产品推荐
相关产品推荐

