XAML GridView ItemTemplate无法绑定到控件

Jua*_*mez 3 c# xaml win-universal-app uwp

我有一个带有ItemTemplate 的GridView,它包含一个Custom控件:

<GridView
    ItemsSource="{Binding Ubicaciones.Ubicaciones}">
    <GridView.ItemTemplate>
        <DataTemplate>
            <ctr:HabitacionControl
                Width="70"
                Height="140"
                Ubicacion="{Binding}"/>
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>
Run Code Online (Sandbox Code Playgroud)

这是我的自定义用户控件:

<UserControl
        x:Class="MySln.Mucama.Controls.HabitacionControl"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:MySln.Mucama.Controls"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="200"
        d:DesignWidth="97">
    <UserControl.DataContext>
        <local:HabitacionControlVM/>
    </UserControl.DataContext>
    <Grid>
        <RelativePanel>
            <Image x:Name="Puerta" Source="ms-appx:///Assets/Puerta.jpg"
                   Grid.RowSpan="5"/>
            <TextBlock Text="{Binding Ubicacion.StrNombreMesa,FallbackValue=####}"
                       HorizontalAlignment="Center"
                       VerticalAlignment="Center"
                       Foreground="AliceBlue"
                       FontWeight="ExtraBold"
                           RelativePanel.AlignHorizontalCenterWithPanel="True"/>
        </RelativePanel>
    </Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

它的代码背后:

public sealed partial class HabitacionControl : UserControl
{
    public HabitacionControl()
    {
        this.InitializeComponent();
    }

    public MyClass Ubicacion
    {
        get { return (MyClass)GetValue(UbicacionProperty); }
        set { SetValue(UbicacionProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Ubicacion.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty UbicacionProperty =
        DependencyProperty.Register("Ubicacion", typeof(MyClass), typeof(HabitacionControl), new PropertyMetadata(new PropertyChangedCallback(OnUbicacionChanged)));

    private static void OnUbicacionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
       //...
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我需要将每个Ubicaciones.Ubicaciones绑定到我的Customcontrol的Ubicación属性.

在运行时,我的gridview生成我的所有项目,但绑定到它的Ubicacion属性永远不会发生.

输出窗口中没有任何警告.

我错过了什么?还是做错了?

小智 10

我的,请看这里:

<UserControl.DataContext>
    <local:HabitacionControlVM/>
</UserControl.DataContext>
Run Code Online (Sandbox Code Playgroud)

有人卖给你一张脏肮脏的货物.可能是那些跑来跑去告诉别人的混蛋之一DataContext = this;是个好主意.

对不起,相切.现在看看这个:

<ctr:HabitacionControl 
    Width="70" 
    Height="140" 
    Ubicacion="{Binding}"/>
Run Code Online (Sandbox Code Playgroud)

我在看什么?那是伪DataContext属性吗?这是一个伪DataContext属性.问题是,Binding对象HabitacionControl 不是其父级的DataContext中的对象.什么是DataContext HabitacionControl

<UserControl.DataContext>
    <local:HabitacionControlVM/>
</UserControl.DataContext>
Run Code Online (Sandbox Code Playgroud)

这就是为什么你不为你的UserControl创建视图模型的原因.你已经打破了数据绑定的工作方式.视图模型必须通过DataContext向下流动.当您中断此流程时,您将失败.

我问你 - TextBox有TextBoxViewModel吗? 不,它有一个绑定的Text属性.你怎么绑它呢?您的视图模型会流入,从而允许您将视图模型的属性绑定到TextBox上公开的属性.TextBox.DataContext

还有其他hacky方法来解决这个问题,但最好的解决方案是首先不要让自己陷入这种状况.

您需要抛弃它HabitacionControlVM并在您的视图模型可以绑定的UserControl表面上公开DependencyProperties,提供您的UserControl需要的任何功能.将UI逻辑放在代码隐藏中HabitacionControl.

不,这不会打破MVVM.UI逻辑在代码隐藏中很好.

如果您HabitacionControlVM正在执行真正不应该在代码隐藏中的繁重工作,那么只需将其重构为您的代码隐藏调用的类.

人们认为UserControlViewModel反模式是应该如何完成的.它真的不是.祝好运.