Xamarin.forms Can';无法从代码中创建的数据模板中获取父绑定上下文
我正在视图模型中用代码创建一个数据模板,并将其绑定到ListView,如下所示Xamarin.forms Can';无法从代码中创建的数据模板中获取父绑定上下文,xamarin.forms,data-binding,Xamarin.forms,Data Binding,我正在视图模型中用代码创建一个数据模板,并将其绑定到ListView,如下所示 <ListView x:Name="MainList ItemTemplate="{Binding JobListTemplate}" 我似乎无法将命令的父(列表视图)绑定上下文正确绑定到vm 我读过一些帖子,建议如果模板与页面不在同一个文件中,可能会出现问题 有什么想法吗?您对源代码引用的设置是错误的。请参阅此链接 var按钮=新建按钮 { Text=“单击我”, }; SetBindin
<ListView
x:Name="MainList
ItemTemplate="{Binding JobListTemplate}"
我似乎无法将命令的父(列表视图)绑定上下文正确绑定到vm
我读过一些帖子,建议如果模板与页面不在同一个文件中,可能会出现问题
有什么想法吗?您对源代码引用的设置是错误的。请参阅此链接
var按钮=新建按钮
{
Text=“单击我”,
};
SetBinding(button.CommandProperty,新绑定(“BindingContext.ClickMeCommand”,来源:listView));
这是一个相当复杂的问题,涉及到各种SO答案和Xamarin论坛帖子,所以我想我应该发布答案
首先,我创建了一个ViewCell类,在其中我用代码组装了ViewCell。注意_favoriteButton变量
public class JobListViewCell : ViewCell
{
private Button _favouriteButton;
public JobListViewCell()
{
BuildViewCell();
}
我创建了按钮并绑定了命令参数属性-这将传递列表视图项
_favouriteButton = new Button();
_favouriteButton.SetDynamicResource(VisualElement.StyleProperty, "IconButtonSolid");
_favouriteButton.Text = FontAwesomeIcons.Heart;
_favouriteButton.SetBinding(Button.CommandParameterProperty, new Binding("."));
我创建了一个名为ParentBindingContext的可绑定属性-这将允许我在buttons命令上更新绑定上下文
//
// ParentBindingContext
//
public static readonly BindableProperty ParentBindingContextProperty =
BindableProperty.Create(nameof(ParentBindingContext), typeof(object),
typeof(JobListViewCell), "", BindingMode.OneWay, null,
OnParentBindingContextPropertyChanged);
private static void OnParentBindingContextPropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
{
if (bindable is JobListViewCell control)
{
control._favouriteButton?.SetBinding(Button.CommandProperty,
new Binding("ToggleIsFavouriteCommand",
BindingMode.Default, null, null, null,
newvalue));
}
}
public object ParentBindingContext
{
get => (object)GetValue(ParentBindingContextProperty);
set => SetValue(ParentBindingContextProperty, value);
}
最后,在我的页面XAML中,我将视图单元格和绑定的ParentBindingContext添加到列表视图中
<ListView
Grid.Row="1"
ItemsSource="{Binding Jobs}"
SelectedItem="{Binding SelectedJob, Mode=TwoWay}"
x:Name="MainList">
<ListView.ItemTemplate>
<DataTemplate>
<viewCells:JobListViewCell
ParentBindingContext="{Binding BindingContext, Source={x:Reference MainList}}">
</viewCells:JobListViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
以下是视图模型中的命令。将传入包含已按下按钮的列表视图项
private Command _toggleIsFavouriteCommand;
public Command ToggleIsFavouriteCommand => _toggleIsFavouriteCommand ??= new Command<JobMaster>(ToggleIsFavourite);
private void ToggleIsFavourite(JobMaster jobMaster)
{
jobMaster.IsFavourite = !jobMaster.IsFavourite;
}
private命令\u toggleisfavorite命令;
公共命令toggleisfavoriteCommand=>\u toggleisfavoriteCommand???=新命令(toggleisfavorite);
专用无效切换IsFavorite(作业主机作业主机)
{
jobMaster.isfavorite=!jobMaster.isfavorite;
}
希望这对其他人有所帮助。数据模板的父级ListView不在代码文件中,因此我认为我无法以这种方式引用它。我尝试了source:“MainList”,但没有成功。@SteveChadbourne—“MainList”应该可以成功-x:Name使变量名在代码隐藏中可见。但是Intellisense在您第一次成功构建之前不会知道这一点。在此之前,您将看到一个生成错误列表。解决方法是将x:Name添加到XAML,构建项目,然后开始向code-behind.FWIW添加所需的内容,在您展示的简单场景中,IMHO可以简单地将
null
作为源代码传入。默认情况下,页面上的所有元素都使用页面的BindingContext
。它应该“刚刚起作用”。不需要对MainList
的引用,除非它或其祖先之一重写了页面的绑定上下文。(虽然我不能100%确定您使用的是Cell
和TemplateBinding
,但从模板上下文到页面的视图层次结构可能需要更多内容。)大约有5-6篇文章讨论了从代码而不是xaml引用父BindingContex的方法。不管什么奇怪的原因。您还应该将此标记为答案。
<ListView
Grid.Row="1"
ItemsSource="{Binding Jobs}"
SelectedItem="{Binding SelectedJob, Mode=TwoWay}"
x:Name="MainList">
<ListView.ItemTemplate>
<DataTemplate>
<viewCells:JobListViewCell
ParentBindingContext="{Binding BindingContext, Source={x:Reference MainList}}">
</viewCells:JobListViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
private Command _toggleIsFavouriteCommand;
public Command ToggleIsFavouriteCommand => _toggleIsFavouriteCommand ??= new Command<JobMaster>(ToggleIsFavourite);
private void ToggleIsFavourite(JobMaster jobMaster)
{
jobMaster.IsFavourite = !jobMaster.IsFavourite;
}