gpt4 book ai didi

wpf - 属性与变量作为 ByRef 参数

转载 作者:行者123 更新时间:2023-12-04 13:47:20 27 4
gpt4 key购买 nike

我创建了一个实现 INotifyPropertyChanged 的基类界面。该类还包含一个通用函数 SetProperty设置任何属性的值并提高 PropertyChanged事件,如有必要。

Public Class BaseClass
Implements INotifyPropertyChanged

Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

Protected Function SetProperty(Of T)(ByRef storage As T, value As T, <CallerMemberName> Optional ByVal propertyName As String = Nothing) As Boolean
If Object.Equals(storage, value) Then
Return False
End If

storage = value
Me.OnPropertyChanged(propertyName)
Return True
End Function

Protected Overridable Sub OnPropertyChanged(<CallerMemberName> Optional ByVal propertyName As String = Nothing)
If String.IsNullOrEmpty(propertyName) Then
Throw New ArgumentNullException(NameOf(propertyName))
End If

RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub

End Class

然后我有一个类,它应该保存一些数据。为简单起见,它仅包含一个属性(在此示例中)。
Public Class Item
Public Property Text As String
End Class

然后我有第三个类,它继承自基类并使用数据保存类。这第三类应该是 WPF 窗口的 ViewModel。

我没有列出 RelayCommand 的代码类,因为你们可能都有自己的实现。请记住,这个类在执行命令时执行给定的函数。
Public Class ViewModel
Inherits BaseClass

Private _text1 As Item 'data holding class
Private _text2 As String 'simple variable
Private _testCommand As ICommand = New RelayCommand(AddressOf Me.Test)

Public Sub New()
_text1 = New Item
End Sub

Public Property Text1 As String
Get
Return _text1.Text
End Get
Set(ByVal value As String)
Me.SetProperty(Of String)(_text1.Text, value)
End Set
End Property

Public Property Text2 As String
Get
Return _text2
End Get
Set(ByVal value As String)
Me.SetProperty(Of String)(_text2, value)
End Set
End Property

Public ReadOnly Property TestCommand As ICommand
Get
Return _testCommand
End Get
End Property

Private Sub Test()
Me.Text1 = "Text1"
Me.Text2 = "Text2"
End Sub

End Class

然后我的 WPF 窗口使用 ViewModel 类作为它的 DataContext .
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfTest"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:ViewModel />
</Window.DataContext>

<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Text1}" Height="24" Width="100" />
<TextBox Text="{Binding Text2}" Height="24" Width="100" />
<Button Height="24" Content="Fill" Command="{Binding TestCommand}" />
</StackPanel>
</Window>

如您所见,此窗口仅包含两个文本框和一个按钮。文本框绑定(bind)到属性 Text1Text2并且按钮应该执行命令 TestCommand .

执行命令时,两个属性 Text1Text2被赋予一个值。而且由于这两个属性都提高了 PropertyChanged事件,这些值应该显示在我的窗口中。

但只有值“Text2”显示在我的窗口中。

房产值(value) Text1是“Text1”,但似乎 PropertyChanged此属性的事件在属性获得其值之前引发。

有什么办法可以改变 SetProperty在我的基类中提高 PropertyChanged 的函数房产升值后?

感谢您的帮助。

最佳答案

实际发生了什么?

这不起作用,因为属性的行为不像字段那样。

当你这样做 Me.SetProperty(Of String)(_text2, value) , 发生的是对字段 _text2 的引用被传递而不是它的值,所以 SetProperty函数可以修改引用中的内容,并修改字段。

但是,当您执行 Me.SetProperty(Of String)(_text1.Text, value) ,编译器看到一个属性的getter,所以它会首先调用_text1的Get属性,然后将返回值的引用作为参数传递。所以当你的函数SetProperty正在接收 ByRef参数,它是 getter 的返回值,而不是实际的字段值。

据我了解here ,如果你说你的属性是 ByRef,当你退出函数调用时,编译器会自动更改字段 ref ......所以这可以解释为什么它在你的事件之后发生变化......

This other blog似乎证实了这种奇怪的行为。

关于wpf - 属性与变量作为 ByRef 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40847193/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com