Binding a UserControl DP from DataTemplate UWP

本秂侑毒 提交于 2019-12-07 08:34:14

问题


I've got a FlipView that shows Figurines. Figurines contain a Path to their image.

Binding this property to a regular DataTemplate is ok. (the code below works fine)

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

But when using my UserControl instead, it doesnt work anymore:

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

The FigurinePath DP is never set. (If I use a hardcoded string, its fine.) Here is the error in the output:

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

It looks like the DataTemplate tries to assign the Figurine as the DataContext of my UserControl, then retrieve the property from my UC's DataContext. But my UC has its own DataContext (its ViewModel) and I don't want to remove it.

Unfortunately with WinRT/UWP there is no FindAncestor tricks that I can do with the Binding. I already tried this: (FlipFigurine being the FlipView object)

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

It doesnt work. Even changing the DP to object and trying the following doesnt work, the setter of the DP is never called. No error in the log though.

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

Is there any way to access the actual Figurine object and simply bind its Path property to the FigurinePath property of my UC??


回答1:


As there is no FindAncestor, I think your only hope is to do little refactoring. Here's a sample which hopefully gives you an idea of how to get around the issue:

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

Here's the main parts from the code:

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()
    {

    }
}

For some reference related to the example, here's an article from Jerry Nixon.



来源:https://stackoverflow.com/questions/34332815/binding-a-usercontrol-dp-from-datatemplate-uwp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!