简体   繁体   中英

WPF Datagrid programmatically added columns bind from list in class

I have an Employee class:

class Employee
{
        public string Name { get; set; }
        public string SurName { get; set; }
        public int Rest{ get; set; }
        public int  Worked { get; set; }
        public List<int> PerShift= new List<int>(); 
}

In my database, I save how many times an employee worked in 1st shift how many in 2nd etc. Then in my datagrid, I want to see how many times each employee worked in total, how many days he rested and how many days he worked in each shift. The thing is that shift number is set by user, so I have to programmatically add those columns

<DataGrid Name="EmployeesStatsDatagrid"
          Grid.Row="1"
          IsReadOnly="True"
          CanUserAddRows="False" CanUserReorderColumns="False"
          Grid.ColumnSpan="4"
          Grid.Column="0"
          IsSynchronizedWithCurrentItem="True"
          CanUserDeleteRows="False"
          CanUserResizeRows="False"
          AutoGenerateColumns="False"
          VerticalAlignment="Stretch">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
        <DataGridTextColumn Header="Surname" Binding="{Binding SureName}" />
        <DataGridTextColumn Header="Rest" Binding="{Binding Rest}" />
        <DataGridTextColumn Header="Δούλεψε" Binding="{Binding Worked}" />
    </DataGrid.Columns>
</DataGrid>

Then I add the extra columns

for (int i = 0; i < Collections.ShiftsCollection.Count; i++)
{
    DataGridTextColumn textColumn = new DataGridTextColumn();
    textColumn.Header = Collections.ShiftsCollection[i].ShiftName.ToUpper();
    //textColumn.Binding = new Binding(Collections.ShiftsCollection[i].ShiftName);
    EmployeesStatsDatagrid.Columns.Add(textColumn);
}

The columns are properly set, I create a list of Employee s and binding works for name, surname, worked and rest, but how can I bind the extra columns to the List<int> PerShift ? Any ideas? Or should I implement it differently?

在此处输入图像描述

For example in this case I have two shifts, morning and afternoon, first employees PerShift list is {4,0} and second is {0,1} is there a way to have those values in the column binded? I hardcoded them in this case but if I sort columns values are lost.

You can use ExpandoObject. Add your extra columns the same way you did, then create the DataGrid.ItemsSource object list as follows:

        var all_items = new List<object>();

        for (int i = 0; i <= MyData.Count-1; i++)
        {
            dynamic item = new System.Dynamic.ExpandoObject();
            item.Name = MyData[i].Name;
            item.Surname = MyData[i].Surname;
            item.Rest = MyData[i].Rest;
            item.Worked = MyData[i].Worked;
            
            for (int k = 0; k <= Collections.ShiftsCollection.Count - 1; k++)
            {
                item = ExtendExpando(item, Collections.ShiftsCollection[k].ShiftName, Collections.ShiftsCollection[k].Value);
                // or whatever corresponding value instead of Collections.ShiftsCollection[k].Value
            }

            all_items.Add(item);
        }

        EmployeesStatsDatagrid.ItemsSource = all_items;

Where ExtendExpando function can be implemented as follows:

public static object ExtendExpando(object OldExpandoObject, string NewProperty, object NewValue)
    {
        var ex = (IDictionary<string, object>)OldExpandoObject;
        ex.Add(new KeyValuePair<string, object>(NewProperty, NewValue));
        dynamic output = ex;
        return output;
    }

Note: I successfully tested this code using Visual Basic not C#, you may need some minor modifications.

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