我有一个 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 属性的绑定。
输出窗口中没有任何警告。
我缺少什么?或者做错了?
答案 0 :(得分:9)
我的,请看这里:
<UserControl.DataContext>
<local:HabitacionControlVM/>
</UserControl.DataContext>
有人卖给你一张脏肮脏的货物。可能是那些经常告诉别人DataContext = this;
的混蛋之一是个好主意。
抱歉,切线。现在看看这个:
<ctr:HabitacionControl
Width="70"
Height="140"
Ubicacion="{Binding}"/>
我看到的是什么?那是伪DataContext属性吗?这是一个伪DataContext属性。问题是Binding
针对HabitacionControl
的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反模式是应该如何完成的。它真的不是。祝你好运。