我有一个由两个类组成的非常简单的复合模型:
Public Class ParentModelVM
Public Property Name As String
Public Property ChildModel As ChildModelVM
Public Sub New()
Name = "A Parent Model"
ChildModel = New ChildModelVM With {.Name = "A Child Model"}
End Sub
End Class
Public Class ChildModelVM
Public Property Name As String
Public Property Description As String
End Class
两者都实现了 INotifyPropertyChanged,我已将其缩写。我正在尝试生成一个用户控件来编辑 ParentModelVM:
<UserControl x:Class="EditParentModel" .../>
<UserControl.DataContext>
<Binding RelativeSource="{RelativeSource Self}" Path="ViewModel" />
</UserControl.DataContext>
<TextBox Name="NameInput" Text="{Binding Path=Name}"/>
<local:EditChildModel x:Name="ChildModelInput" ViewModel="{Binding Path=ChildModel}"/>
</UserControl>
ViewModel 是一个 ParentModelVM,它注册为一个默认绑定双向的 DependencyProperty。我有一个类似的名为 EditChildModel 的 UserControl,它有一个 ChildModelVM 类型的 ViewModel 属性,也注册为默认绑定双向的 DependencyProperty。
这个逻辑对我来说似乎很有意义:ParentModelVM 有一个使用 TextBox 控件编辑的 String,它的 Text 属性绑定,它有一个 ChildModelVM,它使用绑定 ViewModel 属性的 EditChildModel 控件进行编辑。
ParentModelVM.Name 正确绑定到其文本框,并且两个 ChildViewModelVM 属性正确绑定到其文本框。但是,EditParentModel.ViewModel.ChildModel与 EditChildModel.ViewModel不是同一个对象,我不知道为什么。ViewModel="{Binding Path=ChildModel}"
如果我从 EditParentModel UserControl中删除该属性,则整个应用程序的行为完全相同。例如,NameInput 使用“A Parent Model”进行初始化,但 EditChildModel.NameInput 并没有像我预期的那样使用“A Child Model”进行初始化。
对此的任何帮助将不胜感激。谢谢!
- 编辑 -
好的,我已经把它简化到了荒谬的地步,但它仍然不起作用。我有一个名为 SimpleParent 的模型。这是整个代码:
Imports System.ComponentModel
Public Class SimpleParent
Implements INotifyPropertyChanged
Private _someText As String
Public Property SomeText As String
Get
Return _someText
End Get
Set(ByVal value As String)
_someText = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("SomeText"))
End Set
End Property
Public Sub New()
SomeText = "This is some text."
End Sub
Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class
我创建了一个名为“SuperTextControl”的用户控件,它的作用与 TextBox 完全一样,具有一个名为“Says”的 DependencyProperty,而不是 Text。这是整个 XAML:
<UserControl x:Class="SuperTextControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="23" d:DesignWidth="300">
<UserControl.DataContext>
<Binding RelativeSource="{RelativeSource Self}"/>
</UserControl.DataContext>
<TextBox Name="SaysInput" Text="{Binding Path=Says}" />
</UserControl>
这是代码隐藏:
Public Class SuperTextControl
Public Shared ReadOnly SaysProperty As DependencyProperty =
DependencyProperty.Register("Says", GetType(String), GetType(SuperTextControl))
Public Property Says As String
Get
Return CTypeDynamic(Of String)(GetValue(SaysProperty))
End Get
Set(ByVal value As String)
SetValue(SaysProperty, value)
End Set
End Property
End Class
然后我创建了一个 SimpleParentControl,它有一个 SimpleParent DependencyProperty。我将它作为 DP 使用,因为我可能想将此控件嵌套在绑定到 SimpleParent 属性的其他控件中。这是整个 XAML:
<UserControl x:Class="SimpleParentControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfTest"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
<Binding RelativeSource="{RelativeSource Self}" Path="SimpleParent" />
</UserControl.DataContext>
<StackPanel>
<TextBox Text="{Binding Path=SomeText}" />
<local:SuperTextControl Says="{Binding Path=SomeText}" />
</StackPanel>
</UserControl>
以及整个代码隐藏:
Public Class SimpleParentControl
Public Shared ReadOnly SimpleParentProperty As DependencyProperty =
DependencyProperty.Register("SimpleParent", GetType(SimpleParent), GetType(SimpleParentControl))
Public Property SimpleParent As SimpleParent
Get
Return CTypeDynamic(Of SimpleParent)(GetValue(SimpleParentProperty))
End Get
Set(ByVal value As SimpleParent)
SetValue(SimpleParentProperty, value)
End Set
End Property
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
SimpleParent = New SimpleParent()
End Sub
End Class
SimpleParentControl 中的 TextBox 按预期显示“这是一些文本”。local:SuperTextControl 什么也不显示。这是我能想到的创建可重用 UserControl 的最简单示例,但它不起作用。当然,有人已经成功地创建了一个像自定义文本框一样简单的可重复使用的 UserControl,但是没有在线教程专门讨论如何做到这一点。这是一个极其微不足道的示例,似乎无缘无故地失败了。我非常感谢对此的任何见解。谢谢。