【问题标题】:DataGrid Dynamic - Binding/LoadingDataGrid 动态 - 绑定/加载
【发布时间】:2015-09-18 16:15:25
【问题描述】:

我在 C# WPF 中有一个 DataGrid,我想以有组织的方式列出数据,但问题是动态绑定列加载很难处理,因为我的类需要动态字段名称?

代码

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();
            }
        }
    }

问题

如上所示,我的类中似乎需要一个与用户指定名称相同的字段名称。有没有一种方法可以让一个 String 字段使用 benefit.getName() 作为它的名称?如果不是,如何解决绑定基于字段名称这一事实?

每位员工都可以获得多项福利

【问题讨论】:

    标签: c# wpf datagrid


    【解决方案1】:

    如果您查看Binding 构造函数,您会看到该参数称为path,而不是name。考虑到这一点,如果您放置某种名为 let say Benefits 的列表属性,那么您可以使用 Benefits[i] 作为绑定路径。

    例子:

    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>
    

    后面的代码

    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;
            }
        }
    }
    

    结果

    【讨论】:

      【解决方案2】:

      你可以这样做吗?

          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();
              }
          }
      }
      

      使用列表计算每位员工的多项福利:

          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();
              }
          }
      

      【讨论】:

      • 每个员工都有多重福利
      • 这种情况下可以使用列表吗?
      【解决方案3】:

      所以我必须找到一种方法来动态绑定数据或至少逐行插入数据....

      最终放弃了对象绑定的想法并使用了数据表,这是其他人的代码。

      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">
      

      【讨论】:

        猜你喜欢
        • 2023-04-06
        • 1970-01-01
        • 2014-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多