Xaml 如何在UWP中使用相对资源模式查找祖先(或等价物)
我正在尝试做一些人们认为应该非常简单的事情(至少在WPF中是这样)。 我有一个带有列表框和datatemplate的页面,现在datatemplate调用了一个带有按钮的用户控件。没什么特别的,但是buttons命令不是listboxsource的一部分,我找不到一个简单的方法告诉按钮在哪里可以找到该命令。下面是一个场景Xaml 如何在UWP中使用相对资源模式查找祖先(或等价物),xaml,uwp,Xaml,Uwp,我正在尝试做一些人们认为应该非常简单的事情(至少在WPF中是这样)。 我有一个带有列表框和datatemplate的页面,现在datatemplate调用了一个带有按钮的用户控件。没什么特别的,但是buttons命令不是listboxsource的一部分,我找不到一个简单的方法告诉按钮在哪里可以找到该命令。下面是一个场景 <Page x:Class="App1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/p
<Page x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1">
<Page.Resources>
<DataTemplate x:Key="MyDataTemplate">
<local:MyButton />
</DataTemplate>
</Page.Resources>
<ListBox ItemTemplate="{StaticResource MyDataTemplate}" ItemsSource="{Binding Customers}" />
</Page>
<UserControl x:Class="App1.MyButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl, AncestorLevel=2}, Path=DataContext.DeleteCommand}" Content="Delete" />
</UserControl>
请注意,这不会编译,因为在UWP中没有模式查找祖先?我该怎么做呢?我一直在看谷歌,但找不到任何关于它的信息
谢谢在Windows10UWP中有一个叫做
x:Bind
的概念。在x:Bind
中,代码隐藏成为绑定的数据上下文。因此,如果在用户控件的代码隐藏中添加指向视图模型的属性,该属性可用于绑定命令
public class MyButton
{
public ViewModel ButtonViewModel
{
get
{
return ButtonViewModelObject;
}
}
}
在XAML中-
<Button Command="{x:Bind ButtonViewModel.DeleteCommand}" Content="Delete" />
您可以将ElementName与传统绑定一起使用以实现此结果
<Button Command="{Binding DataContext.DeleteCommand, ElementName= UserControlName}" Content="Delete" />
参考-
更新:若要从页面的datacontext访问delete命令,可以使用以下方法,前提是-将usercontrol的datacontext(从customer)更改为页面的datacontext不会影响usercontrol中的任何其他内容
<DataTemplate x:Key="MyDataTemplate">
<local:MyButton DataContext="{Binding DataContext, ElementName = PageName}" />
</DataTemplate>
<Button Command="{Binding DeleteCommand}" Content="Delete" />
答案是依赖属性。我也有同样的问题。 首先,如果没有涉及数据模板,则解决方案是直接的:
(this.Content as FrameworkElement).DataContext = this;
将UserControl构造函数中的DataContext设置为其代码隐藏
如果您计划在DataTemplate中使用您的命令,那么您也需要DependecProperty
例如:
<DataTemplate>
<Button Command="{Binding DataContext.MyCommand, ElementName=ParentName}">
</DataTemplate>
因此,现在当您使用用户控件时,将有一个MyCommand属性,您可以绑定到ViewModel中的任何命令,只要模板父级与您提供的模板父级匹配,并且参数绑定到控件所属的实际项
<usercontrols:button MyCommand="{Binding MyCommandFromViewModel}" CommandParameter="{Binding}"/>
简单的例子:
用户控制代码隐藏
public sealed partial class ListviewUserControl : UserControl
{
public ListviewUserControl()
{
this.InitializeComponent();
(this.Content as FrameworkElement).DataContext = this;
}
public ICommand ButtonCommand
{
get { return (ICommand)GetValue(ButtonCommandProperty); }
set { SetValue(ButtonCommandProperty, value); }
}
// Using a DependencyProperty as the backing store for ButtonCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ButtonCommandProperty =
DependencyProperty.Register("ButtonCommand", typeof(ICommand), typeof(ListviewUserControl), new PropertyMetadata(null));
public ObservableCollection<Item> ItemsSource
{
get { return (ObservableCollection<Item>)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
// Using a DependencyProperty as the backing store for ItemsSource. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(ObservableCollection<Item>), typeof(ListviewUserControl), new PropertyMetadata(new ObservableCollection<Item>()));
}
公共密封部分类ListviewUserControl:UserControl
{
公共ListviewUserControl()
{
this.InitializeComponent();
(this.Content作为FrameworkElement)。DataContext=this;
}
公用ICommand按钮命令
{
获取{return(ICommand)GetValue(ButtonCommandProperty);}
set{SetValue(ButtonCommandProperty,value);}
}
//使用DependencyProperty作为ButtonCommand的后备存储。这将启用动画、样式、绑定等。。。
公共静态只读从属属性ButtonCommandProperty=
Register(“ButtonCommand”、typeof(ICommand)、typeof(ListviewUserControl)、newpropertyMetadata(null));
公共可观察收集项目来源
{
get{return(ObservableCollection)GetValue(ItemsSourceProperty);}
set{SetValue(ItemsSourceProperty,value);}
}
//使用DependencyProperty作为ItemsSource的备份存储。这将启用动画、样式、绑定等。。。
公共静态只读依赖项Property ItemsSourceProperty=
DependencyProperty.Register(“ItemsSource”、typeof(ObservableCollection)、typeof(ListviewUserControl)、new PropertyMetadata(new ObservableCollection());
}
UserControl Xaml:
<Grid>
<ListView ItemsSource="{Binding ItemSource}" x:Name="ListView">
<ListView.ItemTemplate>
<DataTemplate>
<!--some item related content-->
<AppBarButton Icon="Delete" Command="{Binding ButtonCommand, ElementName=ListView}" CommandParameter="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
Page.xaml中的用法:
<Controls:ListviewUserControl ItemsSource="{Binding ViewModelsItemsList}" ButtonCommand="{Binding ViewModelsCommand}"/>
谢谢您的回答,但这对我来说不是一个好的解决方案,因为我将该按钮放在一个单独的用户控件中,以便在许多地方重复使用它。因此,ViewModel在不同的屏幕上会有所不同。如果允许相对源忽略它是哪个viewmodel,它只需查看父对象的datacontext即可。我尝试了ElementName,但在这种情况下它不起作用,它找不到调用页的名称。@adminSoftDK:是否类似于-您在datatemplate内的usercontrol中有按钮,并且delete命令位于页面的datacontext中,其中有列表框
?是的,deletecommand位于页面的datacontext中,但是datatemplate当前的datacontext是针对每个客户的。我可能应该做一个更好的示例,我也尝试过这个。这就快到了,但我还将当前项的Id作为命令参数传递。它们属于原始datacontext,所以按照您刚才所说的操作,将找到该命令,但现在我对命令参数有了相同的操作。感谢您的帮助:)我没有得到usercontrols中绑定需要的最后一部分:button,button command={binding MyCommand}没有任何功能,按钮必须查看模板化的父级或其他内容才能找到依赖项属性?依赖项属性始终位于usercontrols代码后面。它只允许在用户控件中的对象和控件外部的对象之间进行绑定。有时,我将整个ListView放入用户控件中,并为ItemSource创建一个依赖属性,这样我就可以在不同的视图中重用整个列表,我只需绑定ItemSource和不同的命令及其标签,如果它们发生更改,我看到了,这很有意义,我稍后会测试:)非常感谢:)不用担心,我很高兴它能帮助。。。首先有点让人困惑,但一旦你明白了…我在使用附加属性和相对资源自绑定方面分享了一个解决方案
<Grid>
<ListView ItemsSource="{Binding ItemSource}" x:Name="ListView">
<ListView.ItemTemplate>
<DataTemplate>
<!--some item related content-->
<AppBarButton Icon="Delete" Command="{Binding ButtonCommand, ElementName=ListView}" CommandParameter="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
<Controls:ListviewUserControl ItemsSource="{Binding ViewModelsItemsList}" ButtonCommand="{Binding ViewModelsCommand}"/>