我正在尝试创建一个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)
答案 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);
哪个可行?