0

我正在尝试创建一个由 DataGrid 和几个按钮组成的 UserControl。按钮将处理添加/删除行(需要是按钮)。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)
4

1 回答 1

1

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

SomeGrid.ItemsSource = SomeCollection;

SomeCollection.Add(new ItemOfTheRightType());

或者

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

该错误表明如果您使用 Grid.ItemsSource 进行绑定,则不能使用 Grid.Items

编辑:

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

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

在c#中

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

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

  • 解决方案是使用反射:

动态创建 IList 类型的新实例

一个有趣的迟到的答案是:

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

哪个可能有效

于 2012-07-04T15:33:53.617 回答