在UserControl WPF / VB中向Datagrid添加新行

时间:2012-07-04 15:29:27

标签: wpf vb.net datagrid row add

我正在尝试创建一个UserControl,它包含一个DataGrid和几个按钮。按钮将处理添加/删除行(需要是按钮)。 DataGrid绑定到自定义可观察集合。集合属性会有所不同(因此我会自动生成列)。

如何添加新行?通常我只是修改可观察的集合。我已经尝试直接在控件中添加一个新行:

dgMain.Items.Add(New DataGridRow())

但是我收到的错误对我来说并不重要:

  

使用ItemsSource时,操作无效。使用ItemsControl.ItemsSource访问和修改元素。

以下是当前的代码:

Public Class DataGrid

Sub New()
    InitializeComponent()
End Sub

#Region "Dependency Properties"
Public Shared MyItemsSourceProperty As DependencyProperty = DependencyProperty.Register("MyItemsSource", GetType(IEnumerable), GetType(DataGrid))
Public Property MyItemsSource() As IEnumerable
    Get
        Return DirectCast(GetValue(MyItemsSourceProperty), IEnumerable)
    End Get
    Set(value As IEnumerable)
        SetValue(MyItemsSourceProperty, value)
    End Set
End Property

#End Region

#Region "Buttons"
Private Sub btnAdd_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btnAdd.Click
    dgMain.Items.Add(New DataGridRow())
End Sub
#End Region

End Class

所以有人知道如何添加新行吗?

感谢您的帮助。

编辑:这是数据的创建方式:

Dim np As New ObPerson
np.Add(New Person With {.FirstName = "Jane", .LastName = "Mitel", .Age = 18})
np.Add(New Person With {.FirstName = "Joe", .LastName = "Bloggs", .Age = 92})

UserControlInstance.MyItemsSource = np

Public Class ObPerson
    Inherits ObservableCollection(Of Person)
End Class

EDIT2:接受答案的VB版本:

Public Shared Sub AddNewElement(l As IList)
    If l Is Nothing OrElse l.Count = 0 Then
        Throw New ArgumentNullException()
    End If
    Dim obj As Object = Activator.CreateInstance(l(0).[GetType]())
    l.Add(obj)
End Sub

Usage: AddNewElement(MyItemsSource)

1 个答案:

答案 0 :(得分:1)

您需要使用绑定的集合 - 而不是网格上的“Items”属性。 ItemsSource将指向您绑定的集合:

SomeGrid.ItemsSource = SomeCollection;

SomeCollection.Add(new ItemOfTheRightType());

(SomeGrid.ItemsSource as SomeCollection).Add(new ItemOfTheRightType());

错误说如果使用Grid.ItemsSource进行绑定,则无法使用Grid.Items

编辑:

如果您在运行时不知道项类型(可能因为这是使用控件等的第三方而您需要通用的添加方法),则需要在底层接口上调用.Add方法。大多数列表类型都继承自.NET框架中的IList

我不是VB专家,我更喜欢c#所以我会给你c#。您需要首先检查基础类型:

在c#

if(grid.ItemsSource is IList) 
{
    (grid.ItemsSource as IList).Add(new childType()); <-- other issue here..
}

您遇到的问题是,如果要向集合添加新项目并且您不知道列表类型,IList需要将该对象的实例添加到列表中

  • 解决方案是使用反射:

Dynamically creating a new instance of IList's type

一个有趣的迟到答案是:

var collectionType = targetList.GetType().GetProperty("Item").PropertyType; 
var constructor = collectionType.GetConstructor(Type.EmptyTypes); 
var newInstance = constructor.Invoke(null); 

哪个可行?