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

グリッドの「Items」プロパティではなく、バインドされたコレクションを使用する必要があります。ItemsSourceは、バインドされているコレクションを指します。

SomeGrid.ItemsSource = SomeCollection;

SomeCollection.Add(new ItemOfTheRightType());

また

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

このエラーは、Grid.ItemsSourceを使用してバインドしている場合、Grid.Itemsを使用できないことを示しています。

編集:

実行時にアイテムタイプがわからない場合(おそらく、これはコントロールなどを使用するサードパーティであり、汎用のaddメソッドが必要なため)、基になるインターフェイスで.Addメソッドを呼び出す必要があります。ほとんどのリストタイプは、.NETFrameworkの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 に答える