【问题标题】:Adding Items to a DataGrid (MVVM)将项目添加到 DataGrid (MVVM)
【发布时间】:2013-11-18 03:11:06
【问题描述】:

目标

使用模型、视图、视图模型 (MVVM) 的处理方式将自定义类对象 (DamagedItems) 的列表添加到 DataGrid。

我希望用户能够创建损坏部件的条目(在检查机器期间被认为不正确)。

我做了什么

我已经创建了:

  • 一个窗口:wDamagedItems.xaml,其中DataContext 设置为DamagedItemViewModel
  • 一个模型:DamagedItemModel.vb,它实现了INotifyPropertyChanged
  • A ViewModel:DamagedItemViewModel.vb,我在其中设置类的属性,例如我的DamagedItemModel
  • 一个 ObservableCollection:DamagedItemList.vb,它继承了一个 ObservableCollection(Of DamagedItemModel)

由于我的 DataContext 设置为 DamagedItemViewModel,因此我设置属性的方法如下:

Public Class DamagedItemViewModel
    Private _DamagedItem As DamagedItemModel
    Private _Add As ICommand
    Private _DamagedItems As DamagedItemList

    Public Property DamagedItem As DamagedItemModel
        Get
            Return _DamagedItem
        End Get
        Set(value As DamagedItemModel)
            _DamagedItem = value
        End Set
    End Property
    Public Property DamagedItems As DamagedItemList
        Get
            Return _DamagedItems
        End Get
        Set(value As DamagedItemList)
            _DamagedItems = value
        End Set
    End Property

    Public Property Add As ICommand
        Get
            Return _Add
        End Get
        Set(value As ICommand)
            _Add = value
        End Set
    End Property


    Public Sub New()
        DamagedItem = New DamagedItemModel("", "", "")
        DamagedItems = New DamagedItemList
        Add = New DamagedItemAddEntryCommand(Me)
    End Sub

    Public Function CanUpdate() As Boolean
        If DamagedItem.Description = "" Then Return False
        If DamagedItem.Initiales = "" Then Return False
        Return True
    End Function

    Public Sub AddEntry()
        DamagedItems.Add(DamagedItem) 'Items get added to the datagrid
        DamagedItem = New DamagedItemModel 'Does not seem to clear textboxes
    End Sub
End Class

这是我的 XAML 的设置方式:

<DataGrid ItemsSource="{Binding Path=DamagedItems}" AutoGenerateColumns="True" HorizontalAlignment="Stretch" Margin="12,90,12,0" Name="DataGrid1" VerticalAlignment="Top" Height="229" / >

<TextBox Text="{Binding DamagedItem.Description, UpdateSourceTrigger=PropertyChanged}"  Height="23" HorizontalAlignment="Left" Margin="88,24,0,0" VerticalAlignment="Top" Width="249" />
<TextBox Text="{Binding DamagedItem.Initiales, UpdateSourceTrigger=PropertyChanged}" Height="23" HorizontalAlignment="Left" Margin="88,58,0,0" VerticalAlignment="Top" Width="249" />

如您所见,我的文本框绑定到我的模型(它包含在我的 ViewModel 中,它绑定到该窗口的 DataContext)。每当我单击“添加”按钮时,文本框中的任何内容都会添加到 DataGrid,但文本框中的内容会保留在那里。


这一步没问题,我写上我要添加的内容点击“添加”

单击“添加”后,我在 DataGrid 中得到以下结果,这很好。问题是我的文本框仍然充满数据,但模型已被清除(请参阅 DamagedItemViewModel AddEntry 方法之后的代码)。

现在当我尝试添加以下文本时:

  • 描述:“零件弯曲
  • 首字母:“A.C

我得到以下结果:

在描述中键入的第一个字母被输入到 DataGrid 的第一个条目中,然后它会擦除描述文本框中的文本。只有这样我才能继续输入我想要的内容。首字母文本框也会出现同样的情况。

有什么想法吗?如果您希望查看更多我的代码,请建议我应该添加哪一部分。

提前谢谢你!

【问题讨论】:

  • 不要立即创建损坏的项目,而是等到您单击添加来构建它。将文本框更改为绑定到字符串属性 DescriptionInitiales
  • @Shoe Umm ...不确定我是否关注这里。我的属性 DescriptionInitiales 已绑定到 DamagedItemModel.vb 类中的字符串属性。我只是在 ViewModel 中使用一个属性来引用该类
  • 我的意思是你应该设置 ViewModel 属性 DescriptionInitiales 并使用这些属性来填充你的模型。直接绑定到您的模型缺少 MVVM 的要点
  • @Shoe 如果我理解正确,我的 ViewModel 不应该引用包含 Description 和 Initiales 的模型?相反,我应该直接在我的视图模型中拥有属性DescriptionInitiales?那么拥有一个模型有什么意义呢?
  • 您的视图模型应该与您的模型进行交互,而不是您的视图与您的模型。您可以让 viewmodel 属性返回您的模型属性,或者您可以让 viewmodel 属性在某些操作发生时填充您的模型。该模型的重点是数据访问。您将实际数据保存到数据库中,而不是像公共事件、命令和临时视图状态变量这样驻留在视图模型中的额外垃圾

标签: wpf vb.net mvvm datagrid observablecollection


【解决方案1】:

是的,我记得遇到过这个。您必须实施 iNotifyPropertyCHnaged。这就是 viewmodel 类“通知”用户界面绑定的底层属性发生变化的方式:

看这里: http://msdn.microsoft.com/en-us/library/ms743695.aspx

您必须为要反射回视图的每个属性实现此功能。所以我要做的是有一个基本的视图模型类(ViewModelBase,它公开了 RasiePropertyChanged 方法),它实现了 iNotifyPropertyChanged,然后我的视图模型继承自它。然后我在属性的属性集中通知属性发生了变化:

即:

    Public Property Selection As job
        Get
            Return Me._Selection
        End Get
        Set(ByVal value As job)
            If _Selection Is value Then
                Return
            End If
            _PreviousJob = _Selection
            _Selection = value
            RaisePropertyChanged(SelectionPropertyName)
        End Set
    End Property

起初这似乎令人沮丧,但需要保持 MVVM 支持的解耦。它易于实施。

【讨论】:

  • 是的,我在 DamagedItemModel.vb 中的每个属性上都有我的INotifyPropertyChangedsetup。这就是我不明白的……我没有在我的 DamagedItemViewModel 中添加任何INotifyPropertyChanged……这有什么不同吗?
  • Nvm,你是对的。我也在我的 ViewModel 上设置了INotifyPropertyChanged,现在它可以完美运行了。谢谢
  • 很高兴为您提供帮助,如果您从该模型绑定到对象,则 NotifyProperty 更改从该模型起作用,但在这种情况下,该属性来自视图模型。它一直发生在我身上。
猜你喜欢
  • 1970-01-01
  • 2015-10-09
  • 1970-01-01
  • 2017-05-07
  • 1970-01-01
  • 2011-11-19
  • 1970-01-01
  • 2016-01-19
  • 2011-07-29
相关资源
最近更新 更多