简体   繁体   中英

How to dynamically add data to WPF DataGrid

I'm new in WPF and I'd like to visualize data from SQL query to WPF DataGrid. I have problem with a how correctly bind a data:

SqlCommand cmd = new SqlCommand(sql_dotaz, conn);
InfoText.Text += ("Příkaz vytvořen a připojen" + "\n");

try
{
    conn.Open();
    InfoText.Text += ("Připojení otevřeno" + "\n");

    SqlDataReader reader = cmd.ExecuteReader();

    int row_count = reader.FieldCount;  
    ArrayList propoj = new ArrayList();

    for (int i = 0; i < row_count; i++)
    {
        propoj.Add(reader.GetName(i));
        tabView.Columns.Add(new DataGridTextColumn 
            { 
                Header = reader.GetName(i), 
                Binding = new Binding(reader.GetName(i)) 
            });

        //Here is the problem!!!
        tabView.Items.Add(new {propoj[i] = "Hello"});
    }

Problem is when a try to add a new item, it's throws an error. I cannot explicitly set the header name like this (Invitation = "Hello").

I also tried

tabView.Columns.Add(new DataGridTextColumn 
    { 
        Header = reader.GetName(i), 
        Binding = new Binding(reader.GetName(i)) 
    });

string record = reader.GetName(i));
tabView.Items.Add(new {record = "Hello"});

But there is still a problem with the header name - The DataGrid is empty.

Please let me know if you have any ideas. Thanks a lot!

First of all, I don't think anonymous types will work in a binding. You'll somehow have to create a wrapper object for that:

// easiest case
public class DatabaseObject
{
    public List<string> Items = new List<string>();
}

With that, you can easily generate your columns:

// this should be renamed in something like columns or fieldCount...
int row_count = reader.FieldCount;  

for (int i = 0; i < row_count; i++)
{
    tabView.Columns.Add(new DataGridTextColumn 
        { 
            Header = reader.GetName(i), 
            Binding = new Binding("Items[i]") 
        });
}

And fill your DataGrid:

if(reader.HasRows)
{
    do
    {
        DatabaseObject obj = new DatabaseObject();
        for (int i = 0; i < row_count; i++)
        {
            obj.Items.Add(reader.GetString(i));
        }

        tabView.Items.Add(obj);
    }
    while(reader.NextResult());
}

You need to manage this with DataBinding , as you specified WPF like technology in tags.

Example links :

Link1

Link 2

Link 3

if wanna go the easy way:

  1. fill a datatable with your data.
  2. simply bind the itemssource from the datagrid to your datatable. (Read about DataBinding and MVVM)

    <DataGrid ItemsSource="{Binding MyFilledDataTableProperty}" />

  3. set the right datacontext.

In the I find the solution. Maybe it´s not best but it´s work. I create DataSet and SQL Adapter

adapter.Fill(dSet);
this.DataContext = dSet.Tables[0].DefaultView;

and in XAML:

<DataGrid Height="Auto" Width="Auto" Name="tabView3" ItemsSource="{Binding}" />

And now it´s work fine :-)

This is what worked for me:

IN THE XAML FILE:

    <DataGrid Name="YourDataGrid"  CanUserAddRows="true" AutoGenerateColumns="False" RowDetailsVisibilityMode="VisibleWhenSelected" Width="auto" SelectionUnit="FullRow" RowEditEnding="YourDataGrid_RowEditEnding" AddingNewItem="YourDataGrid_AddingNewItem">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="VideoID_column" Binding="{Binding IDVideo, NotifyOnTargetUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="Video ID" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="VideoTitle_column" Binding="{Binding Titlu,NotifyOnTargetUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="Title" Width="auto"/>
            </DataGrid.Columns>
        </DataGrid>

IN THE .CS File

        private void YourDataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
    {
        if (e.EditAction == DataGridEditAction.Commit && isInsertMode == true)
        {
            var vid = e.Row.DataContext as video;

            var context = new YourEntities();
            var Video = new video //video is the class
            {

                IDVideo = vid.IDVideo,
                Titlu = vid.Titlu
            };
            context.videos.Add(Video);
            context.SaveChanges();
        }
    }

    private void YourDataGrid_AddingNewItem(object sender, AddingNewItemEventArgs e)
    {
        isInsertMode = true;
    }

Hope that helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM