简体   繁体   中英

DataGrid Dynamic - Binding/Loading

I have a DataGrid in C# WPF where I want to list data out in a organized fashion but the issue is that the dynamic binding column load is hard to handle as my class would need a dynamic field name?

Code

public EmployeeDataGrid_BiWeek(string fromData, string untilDate, Benefit[] selectedBenefits, Employee[] selectedEmployees)
        {
            InitializeComponent();

            foreach (Benefit benefit in selectedBenefits)
            {
                var col = new DataGridTextColumn();
                col.Header = benefit.getName();
                col.Binding = new Binding(benefit.getName());
              // ^^ the above binding is based on the field name
                mainDataGrid.Columns.Add(col);
            }
            foreach (Employee emp in selectedEmployees)
            {
                mainDataGrid.Items.Add(new BiEmpGridItem(emp));
            }
        }

        public class BiEmpGridItem {
            public string Name { get;set; }
            public string Birthday { get; set;}
// need a field here with the name of the binding?
            public BiEmpGridItem(Employee ee)
            {
                this.Name = ee.lastName + ", " + ee.firstName;
                this.Birthday = ee.getDateOfBirth();
            }
        }
    }

Question

As seen above, it seems like I need a field name in my class with the same name of a user specified name. Is there a way I can make a String field with the benefit.getName() as it's name? If not how would one work around the fact that the binding is based on field name?

EACH EMPLOYEE CAN HAVE MULTIPLE BENEFITS

Can you do something like this?

    public EmployeeDataGrid_BiWeek(string fromData, string untilDate, Benefit[] selectedBenefits, Employee[] selectedEmployees)
    {
        InitializeComponent();

        string[] benefit_name = new string[selectedBenefits.count()];
        int count = 0;
        foreach (Benefit benefit in selectedBenefits)
        {
            var col = new DataGridTextColumn();
            col.Header = benefit.getName();
            benefit_name[count] = benefit.getName();
            col.Binding = new Binding(benefit.getName());
            // ^^ the above binding is based on the field name
            mainDataGrid.Columns.Add(col);
            count++;
        }

        foreach (Employee emp in selectedEmployees)
        {
           BigEmpGridItem item = new BiEmpGridItem(emp);
           int x = ????;   // The number of the benefit for this employee
           item.BenefitName = benefit_name[x];
            mainDataGrid.Items.Add(item);
        }
    }

    public class BiEmpGridItem {
        public string Name { get;set; }
        public string Birthday { get; set;}
        public string BenefitName {get; set;}  // add this
        public BiEmpGridItem(Employee ee)
        {
            this.Name = ee.lastName + ", " + ee.firstName;
            this.Birthday = ee.getDateOfBirth();
        }
    }
}

Using a list to account for multiple benefits per employee:

    public void EmployeeDataGrid_BiWeek(string fromData, string untilDate, Benefit[] selectedBenefits, Employee[] selectedEmployees)
    {
        InitializeComponent();

        List<string> benefit_names = new List<string>();
        int count = 0;

        // Get this employees selected benefits
        foreach (Benefit benefit in selectedBenefits)
        {
            var col = new DataGridTextColumn();
            col.Header = benefit.getName();
            benefit_names.Add(benefit.getName());
            col.Binding = new Binding(benefit.getName());
            // ^^ the above binding is based on the field name
            mainDataGrid.Columns.Add(col);
            count++;
        }

        // Create the grid
        foreach (Employee emp in selectedEmployees)
        {
           BiEmpGridItem item = new BiEmpGridItem(emp);
           item.BenefitName = benefit_names;
           mainDataGrid.Items.Add(item);
        }
    }

       public class BiEmpGridItem 
       {
        public string Name { get;set; }
        public string Birthday { get; set;}
        public List<string> BenefitName {get; set;}  // add this
        public BiEmpGridItem(Employee ee)
        {
            this.Name = ee.lastName + ", " + ee.firstName;
            this.Birthday = ee.getDateOfBirth();
        }
    }

So I had to find a way to dynamically bind data or at least insert data row by row....

Ended up quitting the object binding idea and used a dataTable, here is the code for others.

List<string> dates = new List<string>();
            DataTable dt = new DataTable();
            dt.Columns.Add("Name");
            dt.Columns.Add("BirthDate");
            foreach (String s in company.payDays)
            {
                DateTime compd = DateTime.Parse(s);
                if (compd > startDate && compd < endDate)
                {
                    dates.Add(s);
                    dt.Columns.Add(s);
                }
            }
            foreach (Employee emp in selectedEmployees)
            {
                var row = dt.NewRow();
                row["Name"] = emp.getLastName() + ", " + emp.getFirstName();
                row["BirthDate"] = emp.getDateOfBirth();
                dt.Rows.Add(row);
            }
            mainDataGrid.AutoGenerateColumns = true;
            mainDataGrid.DataContext = dt.DefaultView;

<DataGrid x:Name="mainDataGrid" DockPanel.Dock="Bottom" ItemsSource="{Binding}"  IsReadOnly="True" ClipboardCopyMode="IncludeHeader">

If you look at the Binding constructor, you'll see that the parameter is called path , not name . With that in mind, if you put some sort of list property called let say Benefits , then you can use Benefits[i] as a binding path.

Example:

XAML

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <DockPanel>
        <DataGrid x:Name="dataGrid" DockPanel.Dock="Top"/>
    </DockPanel>
</Window>

code behind

using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var selectedBenefits = Enumerable.Range(1, 10).Select(n => new Benefit { Name = "Benefit" + n }).ToArray();
            var selectedEmployees = Enumerable.Range(1, 20).Select(n => new Employee
            {
                firstName = "FirstName" + n,
                lastName = "LastName" + n,
                dateOfBirth = "DateOfBirth" + n,
                benefits = selectedBenefits.Select((b, i) => "B[" + n + ", " + i + "]").ToArray()
            }).ToArray();
            dataGrid.AutoGenerateColumns = false;
            dataGrid.Columns.Add(new DataGridTextColumn { Header = "Name", Binding = new Binding("Name") });
            dataGrid.Columns.Add(new DataGridTextColumn { Header = "Birthday", Binding = new Binding("Birthday") });
            for (int i = 0; i < selectedBenefits.Length; i++)
                dataGrid.Columns.Add(new DataGridTextColumn { Header = selectedBenefits[i].getName(), Binding = new Binding("Benefits[" + i + "]") });
            foreach (var emp in selectedEmployees)
                dataGrid.Items.Add(new BiEmpGridItem(emp));
        }
    }
    public class Benefit
    {
        public string Name { get; set; }
        public string getName() { return Name; }
    }
    public class Employee
    {
        public string firstName, lastName;
        public string dateOfBirth;
        public string getDateOfBirth() { return dateOfBirth; }
        public string[] benefits;
    }
    public class BiEmpGridItem
    {
        public string Name { get; set; }
        public string Birthday { get; set; }
        public string[] Benefits { get; private set; }
        public string GetBenefit(int index) { return Benefits[index]; }
        public BiEmpGridItem(Employee ee)
        {
            this.Name = ee.lastName + ", " + ee.firstName;
            this.Birthday = ee.getDateOfBirth();
            this.Benefits = ee.benefits;
        }
    }
}

result

在此处输入图片说明

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