IBRA
IBRA

Reputation: 1782

Enable `CanUserAddRows` with dynamically created `DataGrid` columns - WPF

The DataGrid columns are dynamically created in code behind. In order to bind the columns dynamically I have a Dictionary<string, obj> property, with the key as the column header, and the values.

and the columns gets bound to the dictionary like this:

var item = new DataGridTextColumn();
item.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
item.Header = name;
item.Binding = new Binding($"di[{name}].obj") { Mode = BindingMode.TwoWay };

It works fine, but I couldn't figure out how to get the values from the new row form DataGrid

Upvotes: 1

Views: 441

Answers (2)

opewix
opewix

Reputation: 5083

I've created a test project and ExpandoObject worked for me. I was able to display dynamic column "FirstName" and also add new rows by editing grid rows

XAML:

<Grid Margin="0,0,0,56" Loaded="Grid_Loaded_1">
    <DataGrid Name="MyGrid" ItemsSource="{Binding Items}" HorizontalAlignment="Left" Margin="69,33,0,0" VerticalAlignment="Top" Height="220" Width="389"/>
    <Button Content="Button" HorizontalAlignment="Left" Height="22" Margin="339,286,0,-45" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
</Grid>

CS:

public partial class MainWindow : Window
{
    public ViewModel Vm { get; set; }

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Grid_Loaded_1(object sender, RoutedEventArgs e)
    {
        Vm = new ViewModel();
        Vm.Items = new ObservableCollection<ExpandoObject>();
        DataContext = Vm;

        var fieldName = "FirstName";
        var item = new ExpandoObject() as IDictionary<string, Object>;
        item.Add(fieldName, "Adam"); // Dynamically adding new fields

        var eoItem = item as ExpandoObject;
        Vm.Items.Add(eoItem);

        // Dynamically adding new columns
        var col = new DataGridTextColumn();
        col.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
        col.Header = fieldName;
        col.Binding = new Binding(fieldName) { Mode = BindingMode.TwoWay };
        MyGrid.Columns.Add(col);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {

    }
}

public class ViewModel
{
    public ObservableCollection<ExpandoObject> Items { get; set; }
}

Upvotes: 1

Lukasz Cokot
Lukasz Cokot

Reputation: 450

I had similar problem some time ago. Below You can find my solution. Basically I needed to change AddingNewRow event. You will need to change types etc. to meet your needs but this should be rather easy.

private void AddingNewRow(object sender, AddingNewItemEventArgs e)
{
    DictionaryRowData newRow = new DictionaryRowData();
    for (int i = 0; i < dictionaryData.Columns.Count; i++)
    {
        newRow.Cells.Add(new DictionaryCellData());
    }

    e.NewItem = newRow;
}

Sorry, for not matching exactly your case, but I don't have time right now. I hope it will help

Upvotes: 0

Related Questions