我正在尝试做一些人认为应该非常简单的事情(至少在WPF中).我有一个包含listbox和datatemplate的页面,现在datatemplate调用了一个带有按钮的用户控件.没什么好看的,但是按钮命令不是listboxsource的一部分,我找不到一个简单的方法来告诉按钮在哪里查找命令.这是场景
<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>
Run Code Online (Sandbox Code Playgroud)
请注意这不编译,因为在UWP中没有模式找到祖先?我应该怎么做,我一直在看谷歌但是找不到任何关于它的东西.
谢谢
答案是依赖属性.我有同样的问题.首先,如果您没有涉及DataTemplate,那么解决方案是直截了当的:
(this.Content as FrameworkElement).DataContext = this;
Run Code Online (Sandbox Code Playgroud)
您在其构造函数中将UserControl的DataContext设置为其后面的代码.
如果您计划在DataTemplate中使用Command,那么您也需要DependecyProperty.
例:
<DataTemplate>
<Button Command="{Binding DataContext.MyCommand, ElementName=ParentName}">
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
要备份它,您需要为该命令创建一个依赖项属性:
public ICommand MyCommand
{
get { return (ICommand)GetValue(MyCommandProperty); }
set { SetValue(MyCommandProperty, value); }
}
// Using a DependencyProperty as the backing store for MyCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MyCommandProperty =
DependencyProperty.Register("MyCommand", typeof(ICommand), typeof(ownerclass), new PropertyMetadata(0));
Run Code Online (Sandbox Code Playgroud)
因此,现在当您使用用户控件时,您将拥有一个MyCommand属性,只要模板化父项与您提供的项匹配,您就可以绑定到ViewModel中的任何命令,并且参数也绑定到实际项目.控制是其中的一部分.
<usercontrols:button MyCommand="{Binding MyCommandFromViewModel}" CommandParameter="{Binding}"/>
Run Code Online (Sandbox Code Playgroud)
简单的例子:
UserControl代码背后
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>()));
}
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
Page.xaml中的用法:
<Controls:ListviewUserControl ItemsSource="{Binding ViewModelsItemsList}" ButtonCommand="{Binding ViewModelsCommand}"/>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8480 次 |
| 最近记录: |