如何做亲戚模式在UWP

时间:2015-09-30 08:40:58

标签: xaml uwp

我正在尝试做一些人认为应该非常简单的事情(至少在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>

请注意这不能编译,因为在UWP中没有模式找到祖先?我应该怎么做,我一直在看谷歌,但找不到任何相关的东西。

谢谢

2 个答案:

答案 0 :(得分:5)

答案是依赖属性。我有同样的问题。 首先,如果您没有涉及DataTemplate,那么解决方案是直截了当的:

(this.Content as FrameworkElement).DataContext = this;

将UserControl的DataContext在其构造函数中设置为其后面的代码。

如果您计划在DataTemplate中使用您的Command,您也需要DependecyProperty。

示例:

 <DataTemplate>
     <Button Command="{Binding DataContext.MyCommand, ElementName=ParentName}">
 </DataTemplate>

要备份它,您需要为该命令创建一个依赖项属性:

 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));

现在,当您使用用户控件时,您将拥有一个MyCommand属性,只要模板父项与您提供的项匹配,并且参数绑定到控件所属的项目。

<usercontrols:button MyCommand="{Binding MyCommandFromViewModel}" CommandParameter="{Binding}"/>

简单示例:

后面的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>()));



}

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}"/>

答案 1 :(得分:2)

Windows 10 UWP中有一个名为x:Bind的概念。在x:Bind中,后面的代码成为绑定的datacontext。因此,如果您在用户控件的代码后面添加一个属性,指向视图模型,可用于绑定命令。

public class MyButton
{
   public ViewModel ButtonViewModel 
   { 
      get
      { 
          return ButtonViewModelObject;
      }
   }
}    

在XAML中 -

<Button Command="{x:Bind ButtonViewModel.DeleteCommand}" Content="Delete" />

参考 - https://msdn.microsoft.com/en-us/library/windows/apps/mt204783.aspx

                                 OR

您可以将ElementName与传统绑定结合使用以实现结果。

<Button Command="{Binding DataContext.DeleteCommand, ElementName= UserControlName}" Content="Delete" />

参考 - Can't access datacontext of parent

更新:要从页面的datacontext访问delete命令,可以使用以下方法,假设 - usercontrol的datacontext(从客户)更改为页面的datacontext不会影响其他任何存在在usercontrol里面。

<DataTemplate x:Key="MyDataTemplate">
        <local:MyButton DataContext="{Binding DataContext, ElementName = PageName}" />
 </DataTemplate>

<Button Command="{Binding DeleteCommand}" Content="Delete" />