在 WPF 和 MVVM 中使用 ObservableCollections
Working with ObservableCollections in WPF and MVVM
我是 WPF 的新手,我仍然试图了解如何使用 built-in 函数做某事,而不是自己重新发明轮子。
今天我偶然发现了一个问题,我无法用 built-in 函数解决这个问题,而且我不太喜欢我能想到的可能方法。所以希望你能给我指出正确的方向,甚至可以用 built-in 函数命名一个聪明的方法。
因此,为了简单起见,假设我想为可以在 System.Net.Mail
命名空间中找到的 MailMessage
class 编写一个 ViewModel。
Imports System.Collections.ObjectModel
Imports System.Net.Mail
Public Class MailMessageViewModel
Private _message As MailMessage
...
End Class
A MailMessage
object 有一个 属性 To
类型 MailAddressCollection
包含我的 e-mail 的所有收件人作为 MailAddress
objects.
在我的 ViewModel 中,我将 MailAddress
object 中的 collection 包装到一个 ObservableCollection 中。
这是我的第一个问题,我该怎么做。我是否使用:
Public ReadOnly Property Recipients As ObservableCollection(Of MailAddress)
Get
Return New ObservableCollection(Of MailAddress)(_message.To)
End Get
End Property
或者我使用:
Private _recipients As ObservableCollection(Of MailAddress)
Public ReadOnly Property Recipients As ObservableCollection(Of MailAddress)
Get
If _recipients Is Nothing Then
_recipients = New ObservableCollection(Of MailAddress)(_message.To)
End If
Return _recipients
End Get
End Property
我的视图模型现在有一个可绑定的 属性 Recipients
.
现在我希望能够从我的 MailMessage
的 To
collection 中删除一个 e-mail 地址。
但是当我从 ObservableCollection
中删除一个地址时,我的 UI 得到正确更新,但 To
collection 保持不变。如果我直接从 MailMessage
的 To
collection 中删除,ObservableCollection
和 UI 不会反映更改。
我真的必须通过使用 CollectionChanged
事件或对所有更改进行两次(在 ObservableCollection
中)手动连接 ObservableCollection
和相应的源 collection而在真实的 collection) 中?或者有什么我不知道的聪明的 WPF 方式吗?
不要"wrap"任何东西。
只需创建一个视图模型,其中包含发送邮件消息所需的属性。
在将来的某个时刻,您将真正发送消息。例如,用户单击发送按钮,在某处触发 ICommand。 此时,将你的ViewModel转换成一个MailMessage
.
如果没有 lots 代码,您不能 "wrap" 一个集合包含另一个集合。只需几分钟即可将 属性 值从一种类型的实例复制到另一种类型的实例。
如果更改总是从 ObservableCollection 到原始列表,我认为您可以向 ObservableCollection 的 'CollectionChanged' 事件添加一个处理程序。我觉得这样做不会那么麻烦。
AddHandler Recipients.CollectionChanged, AddressOf RecipientsCollChanged
.....
Private Sub RecipientsCollChanged(sender As Object, e As NotifyCollectionChangedEventArgs)
If e.OldItems IsNot Nothing Then
For Each elem In e.OldItems
_message.To.Remove(elem)
Next
End If
End Sub
显然,如果需要,您还可以使用 NotifyCollectionChangedEventArgs 参数中的信息处理修改和向 ObservableCollection 添加元素。
我是 WPF 的新手,我仍然试图了解如何使用 built-in 函数做某事,而不是自己重新发明轮子。
今天我偶然发现了一个问题,我无法用 built-in 函数解决这个问题,而且我不太喜欢我能想到的可能方法。所以希望你能给我指出正确的方向,甚至可以用 built-in 函数命名一个聪明的方法。
因此,为了简单起见,假设我想为可以在 System.Net.Mail
命名空间中找到的 MailMessage
class 编写一个 ViewModel。
Imports System.Collections.ObjectModel
Imports System.Net.Mail
Public Class MailMessageViewModel
Private _message As MailMessage
...
End Class
A MailMessage
object 有一个 属性 To
类型 MailAddressCollection
包含我的 e-mail 的所有收件人作为 MailAddress
objects.
在我的 ViewModel 中,我将 MailAddress
object 中的 collection 包装到一个 ObservableCollection 中。
这是我的第一个问题,我该怎么做。我是否使用:
Public ReadOnly Property Recipients As ObservableCollection(Of MailAddress)
Get
Return New ObservableCollection(Of MailAddress)(_message.To)
End Get
End Property
或者我使用:
Private _recipients As ObservableCollection(Of MailAddress)
Public ReadOnly Property Recipients As ObservableCollection(Of MailAddress)
Get
If _recipients Is Nothing Then
_recipients = New ObservableCollection(Of MailAddress)(_message.To)
End If
Return _recipients
End Get
End Property
我的视图模型现在有一个可绑定的 属性 Recipients
.
现在我希望能够从我的 MailMessage
的 To
collection 中删除一个 e-mail 地址。
但是当我从 ObservableCollection
中删除一个地址时,我的 UI 得到正确更新,但 To
collection 保持不变。如果我直接从 MailMessage
的 To
collection 中删除,ObservableCollection
和 UI 不会反映更改。
我真的必须通过使用 CollectionChanged
事件或对所有更改进行两次(在 ObservableCollection
中)手动连接 ObservableCollection
和相应的源 collection而在真实的 collection) 中?或者有什么我不知道的聪明的 WPF 方式吗?
不要"wrap"任何东西。
只需创建一个视图模型,其中包含发送邮件消息所需的属性。
在将来的某个时刻,您将真正发送消息。例如,用户单击发送按钮,在某处触发 ICommand。 此时,将你的ViewModel转换成一个MailMessage
.
如果没有 lots 代码,您不能 "wrap" 一个集合包含另一个集合。只需几分钟即可将 属性 值从一种类型的实例复制到另一种类型的实例。
如果更改总是从 ObservableCollection 到原始列表,我认为您可以向 ObservableCollection 的 'CollectionChanged' 事件添加一个处理程序。我觉得这样做不会那么麻烦。
AddHandler Recipients.CollectionChanged, AddressOf RecipientsCollChanged
.....
Private Sub RecipientsCollChanged(sender As Object, e As NotifyCollectionChangedEventArgs)
If e.OldItems IsNot Nothing Then
For Each elem In e.OldItems
_message.To.Remove(elem)
Next
End If
End Sub
显然,如果需要,您还可以使用 NotifyCollectionChangedEventArgs 参数中的信息处理修改和向 ObservableCollection 添加元素。