繁体   English   中英

使用ComboBox在DataGridView中显示二级属性

[英]Using ComboBox to show second-level properties in DataGridView

据我了解,ComboBox 列在 DataGridView 中的绑定比标准列更具动态性,并且这种灵活性可用于使用二阶属性中的 DisplayMembers。 这种方法是Aghaei先生在这里首次提到的。

但是,我没有做对。 我的应用程序仍然抛出“名称”不存在的异常。

 public void CreateEmployeeTable()
        {

            DataGridViewComboBoxColumn jobTitleColumn = new DataGridViewComboBoxColumn();
            jobTitleColumn.HeaderText = "Job Title";
            jobTitleColumn.DataPropertyName = "JobTitle";
            jobTitleColumn.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
            jobTitleColumn.DataPropertyName = "ID";
            jobTitleColumn.DataSource = globalEmployeeList;
            jobTitleColumn.ValueMember = "ID";
            jobTitleColumn.DisplayMember = "Name";
            jobTitleColumn.ReadOnly = true;

            employeeGridView.AutoGenerateColumns = false;
            employeeGridView.ColumnCount = 2;
            employeeGridView.Columns[0].HeaderText = "Employee ID";
            employeeGridView.Columns[0].DisplayIndex = 0;
            employeeGridView.Columns[0].DataPropertyName = "ID";
            employeeGridView.Columns[1].HeaderText = "Name";
            employeeGridView.Columns[1].DataPropertyName = "ListView";
            employeeGridView.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            employeeGridView.Columns.Add(jobTitleColumn);
            
            employeeGridView.DataSource = globalEmployeeList;                                                                               
        }

这是 class 定义:

     
    public class EmployeeModel
    {
        public int ID { get; set; }
        public string LastName { get; set; }
        public string FirstName { get; set; }
        public string Nickname { get; set; }
        public DepartmentModel Department { get; set; }
        public TitleModel JobTitle { get; set; }
        public DateTime HireDate { get; set; }
        public List<EmailModel> EmailList { get; set; } = new List<EmailModel>();
        public List<PhoneModel> PhoneList { get; set; } = new List<PhoneModel>();
        public List<RestrictionModel> RestrictionsList { get; set; } = new List<RestrictionModel>();
        public List<CitationModel> CitationsList { get; set; } = new List<CitationModel>();
        public List<CertificationModel> CertificationList { get; set; } = new List<CertificationModel>();

        public string ListView
        {
            get
            {
                return $"{LastName}, {FirstName}";
            }
        }

        public string ToEmailString()
        {
            IEnumerable<string> employeeEmailStrings = EmailList.Select(emmod => emmod.ToString());
            string employeeEmailString = string.Join($"{Environment.NewLine}", employeeEmailStrings);

            IEnumerable<string> certificationStrings = CertificationList.Select(clistmod => clistmod.ToString());
            string certificationString = string.Join($"{Environment.NewLine}", certificationStrings);

            IEnumerable<string> phoneStrings = PhoneList.Select(plistmod => plistmod.ToString());
            string phoneString = string.Join($"{Environment.NewLine}", phoneStrings);

            return $"{FirstName}, {LastName}: {Environment.NewLine} -{JobTitle.Name}- {Environment.NewLine} {employeeEmailString} {Environment.NewLine} {certificationString} {Environment.NewLine} {phoneString}";
        }



        public class EmailModel
        {
            public int ID { get; set; }
            public string Address { get; set; }
            public string Type { get; set; }

            public override string ToString()
            {
                return $"{Address} ({Type})";
            }
        }

        public class PhoneModel
        {
            public int ID { get; set; }
            public string Number { get; set; }
            public string Type { get; set; }
            public override string ToString()
            {
                return $"{Number} ({Type})";
            }

        }
    }

TitleModel 的定义:

    public class TitleModel
    {
        public string Name { get; set; }
        public int ID { get; set; }  

    }
}

为了支持在 DataGridView 中显示导航属性的属性(二级属性) ,我已经在同一篇文章或这个允许显示二级属性并允许编辑它们的示例中共享了一些示例。

在这里我将分享更多示例,每个示例都被编写为一个最小的完整可验证示例,您只需复制并粘贴到一个空表单中,它们就可以工作。

这些是示例:

  • 使用 ToString()
  • 使用单元格格式化
  • 使用 ComboBox 列进行导航 Object
  • 使用 ComboBox 列作为外键列

示例 - 使用 ToString()

何时:您不想更改 Employee 的JobTitle

如何:通过覆盖JobTitleToString方法

class JobTitle
{
    public int Id { get; set; }
    public string Name { get; set; }
    public override string ToString()
    {
        return Name;
    }
}
class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public JobTitle JobTitle { get; set; }
}
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    var jobTitles = new List<JobTitle>() {
        new JobTitle {Id= 1, Name="Manager" },
        new JobTitle {Id= 2, Name="Employee" },
    };
    var employees = new List<Employee>() {
        new Employee{ Id = 1, Name ="John", JobTitle = jobTitles[0] },
        new Employee{ Id = 2, Name ="Jane", JobTitle = jobTitles[1] },
        new Employee{ Id = 3, Name ="Jack", JobTitle = jobTitles[1] },
    };
    var dg = new DataGridView();
    dg.Dock = DockStyle.Fill;
    dg.DataSource = employees;
    this.Controls.Add(dg);
}

示例 - 使用 CellFormatting

何时:您不想更改 Employee 的JobTitle

如何:通过处理DataGridViewCellFormatting事件并将事件 args 的Value设置为JobTitle的字符串表示形式

class JobTitle
{
    public int Id { get; set; }
    public string Name { get; set; }
}
class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public JobTitle JobTitle { get; set; }
}
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    var jobTitles = new List<JobTitle>() {
        new JobTitle {Id= 1, Name="Manager" },
        new JobTitle {Id= 2, Name="Employee" },
    };
    var employees = new List<Employee>() {
        new Employee{ Id = 1, Name ="John", JobTitle = jobTitles[0] },
        new Employee{ Id = 2, Name ="Jane", JobTitle = jobTitles[1] },
        new Employee{ Id = 3, Name ="Jack", JobTitle = jobTitles[1] },
    };
    var dg = new DataGridView();
    dg.Dock = DockStyle.Fill;
    dg.DataSource = employees;
    dg.CellFormatting += (obj, args) =>
    {
        if (args.RowIndex >= 0 &&
            dg.Columns[args.ColumnIndex].DataPropertyName == "JobTitle")
            args.Value = ((Employee)dg.Rows[args.RowIndex].DataBoundItem).JobTitle.Name;
    };
    this.Controls.Add(dg);
}

示例 - 使用 ComboBox 列作为外键列

何时:您希望能够更改EmployeeJobTitle并且您的 model 中有外键列。

方法对该属性使用DataGridViewComboBoxColumn ,拥有一个包含所有职位的数据源,并将DisplayMemberValueMember设置为适当的属性。

class JobTitle
{
    public int Id { get; set; }
    public string Name { get; set; }
}
class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int JobTitleId { get; set; }
}
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    var jobTitles = new List<JobTitle>() {
        new JobTitle {Id= 1, Name="Manager" },
        new JobTitle {Id= 2, Name="Employee" },
    };
    var employees = new List<Employee>() {
        new Employee{ Id = 1, Name ="John", JobTitleId = 1 },
        new Employee{ Id = 2, Name ="Jane", JobTitleId = 2 },
        new Employee{ Id = 2, Name ="Jack", JobTitleId = 2 },
    };
    var dg = new DataGridView();
    dg.Dock = DockStyle.Fill;
    dg.DataSource = employees;
    dg.Columns.Add(new DataGridViewTextBoxColumn() 
    { 
        DataPropertyName = "Id", HeaderText = "Id" 
    });
    dg.Columns.Add(new DataGridViewTextBoxColumn() 
    {
        DataPropertyName = "Name", HeaderText = "Name" 
    });
    dg.Columns.Add(new DataGridViewComboBoxColumn()
    {
        DataPropertyName = "JobTitleId",
        HeaderText = "JobTitleId",
        DataSource = jobTitles,
        ValueMember = "Id",
        DisplayMember = "Name",
    });
    this.Controls.Add(dg);
}

示例 - 使用 ComboBox 列进行导航 Object

何时:您希望能够更改EmployeeJobTitle并且您的 model 中没有外键列,而是希望在 Z20F35E630DAF44DBFA4C3F68F5399D8C8 中使用导航 object。

方法对该属性使用DataGridViewComboBoxColumn ,具有包含所有职位的数据源,无需将DisplayMemberValueMember设置为适当的属性。 然后处理CellFormatting设置单元格的显示值,处理CellParsingComboBox获取值并放入单元格。

class JobTitle
{
    public int Id { get; set; }
    public string Name { get; set; }
    public override string ToString()
    {
        return Name;
    }
}
class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public JobTitle JobTitle { get; set; }
}

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    var jobTitles = new List<JobTitle>() {
        new JobTitle {Id= 1, Name="Manager" },
        new JobTitle {Id= 1, Name="Employee" },
    };
    var employees = new List<Employee>() {
        new Employee{ Id = 1, Name ="John", JobTitle = jobTitles[0] },
        new Employee{ Id = 2, Name ="Jane", JobTitle = jobTitles[1] },
        new Employee{ Id = 2, Name ="Jack", JobTitle = jobTitles[1] },
    };
    var dg = new DataGridView();
    dg.Dock = DockStyle.Fill;
    dg.DataSource = employees;
    dg.Columns.Add(new DataGridViewTextBoxColumn() 
    { 
        DataPropertyName = "Id", HeaderText = "Id" 
    });
    dg.Columns.Add(new DataGridViewTextBoxColumn() 
    {
        DataPropertyName = "Name", HeaderText = "Name" 
    });
    dg.Columns.Add(new DataGridViewComboBoxColumn()
    {
        DataPropertyName = "JobTitle",
        HeaderText = "JobTitle",
        DataSource = jobTitles,
    });
    dg.CellFormatting += (obj, args) =>
    {
        if (args.RowIndex >= 0 &&
            dg.Columns[args.ColumnIndex].DataPropertyName == "JobTitle")
        {
            args.Value = 
        ((Employee)dg.Rows[args.RowIndex].DataBoundItem).JobTitle.ToString();
        }
    };
    dg.CellParsing += (obj, args) =>
    {
        if (args.RowIndex >= 0 &&
            dg.Columns[args.ColumnIndex].DataPropertyName == "JobTitle")
        {
            args.Value = ((ComboBox)dg.EditingControl).SelectedItem;
            args.ParsingApplied = true;
        }
    };
    this.Controls.Add(dg);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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