0

I want to create an editable table and it size is defined by user (size can be 10*10 or 20*20 or 30*30).

--

I found this topic (here) but it's running in WinForms, and the DataGridView is not supported by WPF.

I tried with a DataGrid, but the following row doesn't working :

Me.DataGridTableau.ItemsSource = dt

--

I tried with a RadGridView (Telerik) but rows are only updatable by ItemsSource property, and like I don't know how many columns will be, I can't create an object which represents the table (x properties for x columns).

Can anybody help me?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129

2 Answers2

0

You can set the ItemsSource of a DataGrid to any IEnumerable, including a DataView of a DataTable:

Me.DataGridTableau.ItemsSource = dt.DefaultView
mm8
  • 163,881
  • 10
  • 57
  • 88
  • It's not working, I have a grey area (the setted grid I think) but this is not the expected result. There is another error ? –  Jan 16 '18 at 10:50
  • Well, this is how you set the ItemsSource to a DataTable. I though this what was you were asking. Make sure that the DataTable actually contains any data and ask a new question if you have another issue. – mm8 Jan 16 '18 at 10:51
0

If anybody need it, I found a solution using a RadGridView (Telerik) :

Create this class :

Imports System.Dynamic
Imports System.Collections.Generic
Imports System.ComponentModel

Public Class MyDataRow
    Inherits DynamicObject
    Implements INotifyPropertyChanged

    ReadOnly data As IDictionary(Of String, Object)

    Public Sub New()
        data = New Dictionary(Of String, Object)()
    End Sub

    Public Sub New(ByVal source As IDictionary(Of String, Object))
        data = source
    End Sub

    Public Overrides Function GetDynamicMemberNames() As IEnumerable(Of String)
        Return data.Keys
    End Function

    Public Overrides Function TryGetMember(ByVal binder As GetMemberBinder, ByRef result As Object) As Boolean
        result = Me(binder.Name)
        Return True
    End Function

    Public Overrides Function TrySetMember(ByVal binder As SetMemberBinder, ByVal value As Object) As Boolean
        Me(binder.Name) = value
        Return True
    End Function

    Default Public Property Item(ByVal columnName As String) As Object
        Get
            If data.ContainsKey(columnName) Then
                Return data(columnName)
            End If

           Return Nothing
        End Get

    Set(ByVal value As Object)
        If Not data.ContainsKey(columnName) Then
            data.Add(columnName, value)
            OnPropertyChanged(columnName)
        Else
            If data(columnName) <> value Then
                data(columnName) = value
                OnPropertyChanged(columnName)
            End If
        End If
    End Set
End Property

Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

Protected Sub OnPropertyChanged(name As String)
    Try
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
    Catch
        If Debugger.IsAttached Then Debugger.Break()
        Throw ' rethrow exception
    End Try
End Sub
Protected Sub OnPropertyChanged(event_args As PropertyChangedEventArgs)
    RaiseEvent PropertyChanged(Me, event_args)
End Sub

End Class

In your VM, you need a public property :

    Private _tableau As ObservableCollection(Of MyDataRow)
Public Property Tableau() As ObservableCollection(Of MyDataRow)
    Get
        Return _tableau
    End Get
    Set(ByVal value As ObservableCollection(Of MyDataRow))
        _tableau = value
        OnPropertyChanged("Tableau")
    End Set
End Property

You need to create a method to load your table :

   Private Function LoadTableau() As ObservableCollection(Of MyDataRow)
    Dim taille As Integer = Me.GetTailleTableau()
    If taille = 0 Then Return Nothing

    Dim data As New ObservableCollection(Of MyDataRow)()

    For i As Integer = 0 To (taille - 1)
        Dim row = New MyDataRow()

        For j As Integer = 0 To (taille - 1)
            'row(String.Format("Column{0}", j)) = String.Format("Cell {0} {1}", i, j)
            row(j) = ""
        Next

        data.Add(row)
    Next

    Return data
End Function

You need to load your table :

Me.Tableau = Me.LoadTableau()

And you need to bind your table :

<telerik:RadGridView x:Name="RadGridViewTableau" ItemsSource="{Binding Tableau}" >

I hope this help :)