从 DataTemplate UWP 绑定 UserControl DP
Binding a UserControl DP from DataTemplate UWP
我有一个显示 Figurines 的 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。 (如果我使用硬编码字符串,没问题。)
这是输出中的错误:
Error: BindingExpression path error: 'Path' property not found on 'Com.Test.ViewModels.UserControl.FigurineStickerUserControlViewModel, eSmart.ViewModels, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. BindingExpression: Path='Path' DataItem='Com.Test.ViewModels.UserControl.FigurineStickerUserControlViewModel, Test.ViewModels, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'Com.Test.Views.FigurineStickerUserControl' (Name='pageRoot'); target property is 'FigurinePath' (type 'Object')
看起来 DataTemplate 试图将 Figurine 指定为我的 UserControl 的 DataContext,然后从我的 UC 的 DataContext 中检索 属性。但是我的 UC 有自己的 DataContext(它的 ViewModel),我不想删除它。
不幸的是 WinRT/UWP 没有我可以使用绑定执行的 FindAncestor 技巧。我已经试过了:(FlipFigurine 是 FlipView 对象)
<local:FigurineStickerUserControl Width="660" Height="372"
FigurinePath="{Binding SelectedItem.Path, ElementName=FlipFigurine}"/>
没用。即使将 DP 更改为 object 并尝试以下操作也不起作用,永远不会调用 DP 的 setter 。不过日志中没有错误。
FigurinePath="{Binding SelectedItem, ElementName=FlipFigurine}"
有什么方法可以访问实际的 Figurine 对象并简单地将其 Path 属性 绑定到 FigurinePath 属性 我的 UC??
因为没有FindAncestor,我认为你唯一的希望就是做一点重构。这是一个示例,希望能让您了解如何解决该问题:
https://github.com/mikoskinen/uwpusercontrolbinding/tree/master
以下是代码的主要部分:
MainPage.xaml
<DataTemplate>
<local:MyUserControl Width="660" Height="372" FigurinePath="{Binding Path}"/>
</DataTemplate>
MainPage.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()
{
}
}
有关示例的一些参考,这里是 article from Jerry Nixon.
我有一个显示 Figurines 的 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。 (如果我使用硬编码字符串,没问题。) 这是输出中的错误:
Error: BindingExpression path error: 'Path' property not found on 'Com.Test.ViewModels.UserControl.FigurineStickerUserControlViewModel, eSmart.ViewModels, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. BindingExpression: Path='Path' DataItem='Com.Test.ViewModels.UserControl.FigurineStickerUserControlViewModel, Test.ViewModels, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'Com.Test.Views.FigurineStickerUserControl' (Name='pageRoot'); target property is 'FigurinePath' (type 'Object')
看起来 DataTemplate 试图将 Figurine 指定为我的 UserControl 的 DataContext,然后从我的 UC 的 DataContext 中检索 属性。但是我的 UC 有自己的 DataContext(它的 ViewModel),我不想删除它。
不幸的是 WinRT/UWP 没有我可以使用绑定执行的 FindAncestor 技巧。我已经试过了:(FlipFigurine 是 FlipView 对象)
<local:FigurineStickerUserControl Width="660" Height="372"
FigurinePath="{Binding SelectedItem.Path, ElementName=FlipFigurine}"/>
没用。即使将 DP 更改为 object 并尝试以下操作也不起作用,永远不会调用 DP 的 setter 。不过日志中没有错误。
FigurinePath="{Binding SelectedItem, ElementName=FlipFigurine}"
有什么方法可以访问实际的 Figurine 对象并简单地将其 Path 属性 绑定到 FigurinePath 属性 我的 UC??
因为没有FindAncestor,我认为你唯一的希望就是做一点重构。这是一个示例,希望能让您了解如何解决该问题:
https://github.com/mikoskinen/uwpusercontrolbinding/tree/master
以下是代码的主要部分:
MainPage.xaml
<DataTemplate>
<local:MyUserControl Width="660" Height="372" FigurinePath="{Binding Path}"/>
</DataTemplate>
MainPage.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()
{
}
}
有关示例的一些参考,这里是 article from Jerry Nixon.