如何在独立DataTemplate中正确绑定ViewModel的属性和命令
问题
我有一个包含ListView的页面用于展示对象列表,按照官方指引将DataTemplate拆分到独立文件后,原本正常的列表条目编辑、删除功能失效了。这些功能通过ViewCell的ContextActions下的MenuItem提供入口,处理编辑、删除的命令定义在ContentPage的BindingContext也就是ViewModel中,拆分后命令无法触发。
已尝试的方案
我试过多种绑定写法,包括FindAncestorBindingContext和FindAncestor两种RelativeSource模式,以及多种AncestorType配置:
{Binding BindingContext.EditCommand, Source={RelativeSource Mode=FindAncestor, AncestorType={x:Type ContentPage}}} {Binding Source={RelativeSource Mode=FindAncestorBindingContext, AncestorType={x:Type views:LoginView}}, Path=EditCommand} {Binding Source={RelativeSource AncestorType={x:Type vm:LoginVM}}, Path=BindingContext.EditCommand}
我的基础代码结构如下:
ContentPage(LoginView)代码
.... <ContentPage.BindingContext> <vm:LoginVM x:Name="viewmodel"/> </ContentPage.BindingContext> <ContentPage.Content> .... <Frame HasShadow="True" Padding="30" VerticalOptions="End" BackgroundColor="{DynamicResource PageBackgroundColor}"> <ListView ItemsSource="{Binding sessionList}" SelectedItem="{Binding SelectedItem}" HasUnevenRows="True" > <ListView.ItemTemplate> <DataTemplate> <templates:LoginSessionTemplate/> </DataTemplate> </ListView.ItemTemplate> </ListView> </Frame> </ContentPage.Content>
独立DataTemplate代码
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:views="clr-namespace:PIM.View" x:Class="PIM.DataTemplates.LoginSessionTemplate"> <ViewCell.ContextActions> <MenuItem Command="{Binding Source={RelativeSource AncestorType={x:Type views:LoginView}}, Path=EditCommand}" CommandParameter="{Binding .}" Text="Edit"/> </ViewCell.ContextActions> ....
拆分后DataTemplate和数据对象的绑定正常,仅ViewModel命令绑定失效:上下文菜单可以正常弹出,按钮文字显示正确,但命令始终不执行,也无法找到对应的ViewModel BindingContext。
解决方案
经排查,FindAncestor模式在该场景下不生效,需要通过遍历XAML层级来引用ViewModel:给DataTemplate的ViewCell设置x:Name参数,绑定时引用该名称,通过访问ViewCell的父级元素获取ViewModel。绑定写法如下:
{Binding Parent.Parent.BindingContext.MyCommand, Source={x:Reference ViewCellName}}
修改后的DataTemplate代码:
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:views="clr-namespace:PIM.View" x:Class="PIM.DataTemplates.LoginSessionTemplate" x:Name="VC"> <ViewCell.ContextActions> <MenuItem Command="{Binding Parent.Parent.BindingContext.EditCommand, Source={x:Reference VC}}" CommandParameter="{Binding .}" Text="Edit"/> </ViewCell.ContextActions> ....
内容的提问来源于stack exchange,提问作者Silent Pants
相关产品推荐
相关产品推荐

