XAML GridView ItemTemplate 未绑定到控件

XAML GridView ItemTemplate not binding to control

我有一个 GridView 和一个包含自定义控件的 ItemTemplate:

<GridView
    ItemsSource="{Binding Ubicaciones.Ubicaciones}">
    <GridView.ItemTemplate>
        <DataTemplate>
            <ctr:HabitacionControl
                Width="70"
                Height="140"
                Ubicacion="{Binding}"/>
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>

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

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

及其背后的代码:

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)
    {
       //...
    }
}

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

在 运行 时,我的 gridview 生成了我所有的项目,但绑定到它的 Ubicacion 属性 从未发生过。

输出中没有任何警告 window。

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

我的我的,看这里:

<UserControl.DataContext>
    <local:HabitacionControlVM/>
</UserControl.DataContext>

有人卖给你一张肮脏、肮脏的商品单。可能是那些 运行 到处告诉人们 DataContext = this; 是个好主意的混蛋之一。

对不起,切线。现在看看这个:

<ctr:HabitacionControl 
    Width="70" 
    Height="140" 
    Ubicacion="{Binding}"/>

我看到了什么?那是伪 DataContext 属性 吗?那是一个伪 DataContext 属性。问题是 BindingHabitacionControl 的 DataContext 中的对象起作用,而不是它的父对象 HabitacionControl 的 DataContext 是什么?

<UserControl.DataContext>
    <local:HabitacionControlVM/>
</UserControl.DataContext>

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

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

还有其他巧妙的方法可以解决这个问题,但最好的解决办法是一开始就不要让自己陷入这种情况。

您需要放弃 HabitacionControlVM 并在您的 UserControl 表面公开 DependencyProperties,您的视图模型可以与之绑定,提供您的 UserControl 运行所需的任何内容。将您的 UI 逻辑放在 HabitacionControl.

的代码隐藏中

不,这不会破坏 MVVM。 UI 代码隐藏中的逻辑很好。

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

人们认为 UserControlViewModel 反模式应该如何实现。真的不是。祝你好运。