【问题标题】:Working with ObservableCollections in WPF and MVVM在 WPF 和 MVVM 中使用 ObservableCollections
【发布时间】:2015-12-10 15:55:33
【问题描述】:

我对 WPF 还很陌生,但我仍在尝试了解如何使用内置函数来做某事,而不是再次自己发明轮子。

今天我偶然发现了一个问题,我无法用内置函数解决,而且我能想到的可能方法我不太喜欢。所以希望你能指出我正确的方向,甚至可以用内置函数命名一个聪明的方法。

因此,为了简单起见,假设我想为 MailMessage 类编写一个 ViewModel,该类可以在 System.Net.Mail 命名空间中找到。

Imports System.Collections.ObjectModel
Imports System.Net.Mail

Public Class MailMessageViewModel
    Private _message As MailMessage

    ...

End Class

MailMessage 对象具有(除其他外)MailAddressCollection 类型的属性 To,其中包含作为 MailAddress 对象的我的电子邮件的所有收件人。

在我的 ViewModel 中,我将这个 MailAddress 对象集合包装到 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

现在我希望能够从我的MailMessageTo 集合中删除一个电子邮件地址。 但是当我从ObservableCollection 中删除地址时,我的用户界面会正确更新,但To 集合保持不变。如果我直接从我的MailMessageTo 集合中删除,ObservableCollection 和因此我的 UI 不会反映这些更改。

我真的必须使用CollectionChanged 事件手动连接ObservableCollection 和相应的源集合吗,或者通过两次进行所有更改(在ObservableCollection 和实际集合中)?还是有什么我不知道的聪明的 WPF 方式?

【问题讨论】:

    标签: wpf mvvm observablecollection


    【解决方案1】:

    不要“包装”任何东西。

    只需创建一个包含发送邮件所需属性的视图模型。

    在未来的某个时候,您实际上会发送消息。例如,用户单击在某处触发 ICommand 的发送按钮。 此时,将您的 ViewModel转换为MailMessage

    如果没有很多代码,您不能将一个集合“包装”在另一个集合中。只需几分钟即可将属性值从一种类型的实例复制到另一种类型的实例。

    【讨论】:

    • 这是正确的方法。如果您直接与模型交互(即从模型中删除项目列表),您会改变模型,如果您对它们不满意,它会消除丢弃更改的可能性。
    【解决方案2】:

    如果更改总是从 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 的修改和添加元素。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-23
      • 1970-01-01
      • 2021-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多