Binding a UserControl DP from DataTemplate UWP

本文关键字:DataTemplate UWP from DP UserControl Binding | 更新日期: 2023-09-27 18:27:06

我有一个FlipView,它显示图形。图形包含其图像的路径

将此属性绑定到常规DataTemplate是可以的。(下面的代码运行良好)

</DataTemplate>
    <Canvas x:Name="DefaultImageCanvas" Width="660" Height="372">
        <Image Name="imageFlip" Width="660" Height="372" Source="{Binding Path}"
            Stretch="Uniform" />
    </Canvas>
</DataTemplate>

但当使用我的UserControl时,它就不再工作了:

<DataTemplate>
    <local:FigurineStickerUserControl Width="660" Height="372"
                                      FigurinePath="{Binding Path}"/>
</DataTemplate>

FigurinePath DP从未设置。(如果我使用硬编码字符串,那没关系。)以下是输出中的错误:

错误:BindingExpression路径错误:在"Com.Test.ViewModels.UserControl.FigureStickerUserControlViewModel,eSmart.ViewModels,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"上找不到"path"属性。BindingExpression:Path='Path'DataItem='Com.Test.ViewModels.UserControl.FigureStickerUserControlViewModel,Test.ViewModels,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null';目标元素是"Com.Test.Views.FigurineStickerUserControl"(名称="pageRoot");目标属性为"FigurinePath"(类型为"Object")

看起来DataTemplate试图将Figurie分配为我的UserControl的DataContext,然后从我的UC的DataContext中检索属性。但是我的UC有自己的DataContext(它的ViewModel),我不想删除它

不幸的是,使用WinRT/UWP,我无法使用绑定来完成FindAncestor技巧。我已经尝试过了:(FlipFigurie是FlipView对象)

<local:FigurineStickerUserControl Width="660" Height="372"
                                  FigurinePath="{Binding SelectedItem.Path, ElementName=FlipFigurine}"/>

它不起作用。即使将DP更改为object并尝试以下操作也不起作用,也永远不会调用DP的setter。不过日志中没有错误。

FigurinePath="{Binding SelectedItem, ElementName=FlipFigurine}"

是否有任何方法可以访问实际的Figurine对象,并简单地将其Path属性绑定到我的UC的FigurinePath特性??

Binding a UserControl DP from DataTemplate UWP

由于没有FindAncestor,我认为您唯一的希望是很少进行重构。这里有一个样本,希望能让你了解如何绕过这个问题:

https://github.com/mikoskinen/uwpusercontrolbinding/tree/master

以下是代码的主要部分:

主页.xaml

<DataTemplate>
    <local:MyUserControl Width="660" Height="372" FigurinePath="{Binding Path}"/>
</DataTemplate>

主页.xaml.cs

private ObservableCollection<MyUserControlVm> coll;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    coll = new ObservableCollection<MyUserControlVm>();
    coll.Add(new MyUserControlVm("http://libcloud.readthedocs.org/en/latest/_images/azure.jpg"));
    coll.Add(new MyUserControlVm("http://www.nimbo.com/wp-content/uploads/windows-azure-logo-nimbo1.png"));
    this.Flip.ItemsSource = coll;
    base.OnNavigatedTo(e);
}

MyUserControl.xaml

<Grid>
    <Canvas Width="660" Height="372">
        <Image Width="660" Height="372" Source="{Binding FigurinePath}" Stretch="Uniform" />
    </Canvas>
</Grid>

MyUserControl.xaml.cs

public sealed partial class MyUserControl : UserControl
{
    public static readonly DependencyProperty FigurinePathProperty = DependencyProperty.Register(
        "FigurinePath", typeof (Uri), typeof (MyUserControl), new PropertyMetadata(default(Uri)));
    public Uri FigurinePath
    {
        get { return (Uri) GetValue(FigurinePathProperty); }
        set { SetValue(FigurinePathProperty, value); }
    }
    public MyUserControl()
    {
        this.InitializeComponent();
        (this.Content as FrameworkElement).DataContext = this;
    }
}

MyUserControlVM.cs

public class MyUserControlVm
{
    public Uri Path { get; set; }
    public MyUserControlVm(string url)
    {
        Path = new Uri(url);
    }
    public void VmAction()
    {
    }
}

关于这个例子的一些参考,这里有一篇来自Jerry Nixon的文章。