WPF 依赖项属性 - 从 XAML 设置



我正在尝试在WPF个人理财应用程序中实现以下目标:

在各个地方,我想显示一个用户控件,提供资产持有(通常是股票、债券等(的详细信息,目标资产可能会由用户动态更改,在这种情况下,必须刷新控件。每个资产都有一个唯一的标识符,即资产 ID。

我正在使用 MVVM,并且开发了一个带有视图模型的窗口,该窗口将 AssetID 作为参数(属性(并检索绑定到视图的相关详细信息。这工作正常。我想做的是制作一个具有相同功能的通用用户控件,这样我基本上可以将该"窗口"放在其他窗口中。

所以我几乎将 XAML 从该窗体复制粘贴到用户控件中,我正在努力将 AssetId 从父窗口传递到子控件。

谷歌告诉我我需要一个依赖属性,这就是我所在的地方


Public Class HoldingView
Private _AssetId As Integer
Public AssetIdProperty As DependencyProperty = DependencyProperty.Register("AssetId",
                GetType(Integer),
                GetType(HoldingView),
                New FrameworkPropertyMetadata(New PropertyChangedCallback(AddressOf AssetIDChanged)))
Public Property AssetId As Integer
Get
Return GetValue(AssetIdProperty)
End Get
Set(value As Integer)
SetValue(AssetIdProperty, value)
End Set
End Property
Private Sub AssetIDChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
Dim NewAssetId As Integer
NewAssetId = e.NewValue
Me.DataContext.AssetId = NewAssetId
End Sub
Public Sub New()
' This call is required by the designer.
InitializeComponent()
Me.DataContext = New HoldingViewmodel
End Sub
End Class 

这样称呼:

<Grid>
<local:HoldingView AssetId="{Binding AssetId}"/>
</Grid>

代码编译并运行,但是当我尝试加载具有用户控件的窗口时,应用程序崩溃并显示以下消息:

不能在类型为"HoldingView"的"AssetId"属性上设置"绑定"。"绑定"只能在依赖对象的依赖属性上设置。

这不是那么有帮助。从我的谷歌搜索中,如果 DP 注册的语法不正确,您也可以收到此消息,但在我经验不足的眼睛看来还可以......

还有其他人有这个吗?

Public AssetIdProperty As DependencyProperty

应该是

Public Shared ReadOnly AssetIdProperty As DependencyProperty

请查看自定义依赖项属性。

同时删除

Me.DataContext = New HoldingViewmodel

因为这将有效地破坏任何基于 DataContext 的绑定,例如

AssetId="{Binding AssetId}"

其中,源属性应由继承的 DataContext 中的对象拥有,该对象通常是应用程序视图模型中的对象。

控件永远不应该有自己的"私有"视图模型,而应该处理代码隐藏中的属性更改。对于 UserControls,其 XAML 中可能只有绑定到 UserConrol 自己的属性的 UI 元素。

因此

Me.DataContext.AssetId = NewAssetId

在 PropertyChangedCallback 是没有意义的,应该删除,以及

Private _AssetId As Integer

总而言之,它应该看起来像这样:

Public Class HoldingView
Public Shared ReadOnly AssetIdProperty As DependencyProperty =
DependencyProperty.Register(
"AssetId",
GetType(Integer),
GetType(HoldingView),
New FrameworkPropertyMetadata(
New PropertyChangedCallback(AddressOf AssetIdPropertyChanged)))
Public Property AssetId As Integer
Get
Return GetValue(AssetIdProperty)
End Get
Set(value As Integer)
SetValue(AssetIdProperty, value)
End Set
End Property
Private Shared Sub AssetIdPropertyChanged(
d As DependencyObject, e As DependencyPropertyChangedEventArgs)
CType(d, HoldingView).AssetIdChanged(e.NewValue)
End Sub
Private Sub AssetIdChanged(id As Integer)
...
End Sub
Public Sub New()
InitializeComponent()
End Sub
End Class 

最新更新