关联两个类,以便组合框与第二个类一起显示
本文关键字:组合 第二个 显示 一起 关联 两个 | 更新日期: 2023-09-27 18:33:38
我有一个Winforms应用程序。有两个类。一个类存储为书籍做出贡献的人员。另一个类是可能的贡献类型(如编辑者、审阅者等(的列表。
BookContributors 类是我的 datagridview 的数据源,工作得很好。现在,我想让 BookContributorTypes 类成为为 BookContributors 类提供信息的组合框。
到目前为止,在我的阅读中,看起来我有很多选择,包括强制组合框进入 datagridview,使用类属性,在类之间创建一对多关系。
由于我的代码将有许多此类情况,因此我想正确地执行此操作。我认为这意味着以某种方式显示两个类之间的关系,以便 datagridview 知道只显示组合框,但我不确定如何做到这一点。
图书投稿人由填写投稿人的人填充。例:书籍贡献者="约翰·史密斯";BookContributorFileAs="Smith, John";BookContributorType = "rev"。
public class BookContributors : INotifyPropertyChanged
{
private string _bookContributor;
[DescriptionLocalized(typeof(ResourcesClassBooks), "BookContributorComment")]
[DisplayNameLocalized(typeof(ResourcesClassBooks), "BookContributorDisplayName")]
public string BookContributor
{
get { return _bookContributor; }
set
{
if (SetField(ref _bookContributor, value, "BookContributor"))
{
// When the user types an author name, add the sorted name to the sorted field.
// ex Name = William E Raymond
// ex File As = Raymond, William E
var name = _bookContributor.Split(' ');
if (name.Length >= 2)
{
string fileAsName = (name[name.Length - 1] + ",");
for (int i = 0; i <= (name.Length - 2); i++)
{
fileAsName = fileAsName + " " + name[i];
}
BookContributorFileAs = fileAsName;
}
}
}
}
private string _bookContributorFileAs;
[DescriptionLocalized(typeof(ResourcesClassBooks), "BookContributorFileAsComment")]
[DisplayNameLocalized(typeof(ResourcesClassBooks), "BookContributorFileAsDisplayName")]
public string BookContributorFileAs { get { return _bookContributorFileAs; } set { SetField(ref _bookContributorFileAs, value, "BookContributorFileAs"); } }
private string _bookContributorType;
[DescriptionLocalized(typeof(ResourcesClassBooks), "BookContributorTypeComment")]
[DisplayNameLocalized(typeof(ResourcesClassBooks), "BookContributorTypeDisplayName")]
public string BookContributorType { get { return _bookContributorType; } set { SetField(ref _bookContributorType, value, "BookContributorType"); } }
#region handle property changes
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetField<T>(ref T field, T value, string propertyName)
{
//if the value did not change, do nothing.
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
//the value did change, so make the modification.
field = value;
return true;
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
BookContributorType(填充 XML 文件中的 bookContributor 类型列表(。示例书籍贡献者类型 ID:"rev"、"edt"。示例图书投稿人类型说明:"审阅者"、"编辑"。
class BookContributorTypes : INotifyPropertyChanged
{
private string _bookContributorTypeId;
[DescriptionLocalized(typeof(ResourcesClassBooks), "BookContributorTypeIdComment_lkp")]
[DisplayNameLocalized(typeof(ResourcesClassBooks), "BookContributorTypeIdDisplayName_lkp")]
public string BookContributorTypeId { get { return _bookContributorTypeId; } set { SetField(ref _bookContributorTypeId, value, "BookContributorTypeId"); } }
private string _bookContributorTypeDescription;
[DescriptionLocalized(typeof(ResourcesClassBooks), "BookContributorTypeComment_lkp")]
[DisplayNameLocalized(typeof(ResourcesClassBooks), "BookContributorTypeDisplayName_lkp")]
public string BookContributorTypeDescription { get { return _bookContributorTypeDescription; } set { SetField(ref _bookContributorTypeDescription, value, "BookContributorTypeDescription"); } }
#region handle property changes
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetField<T>(ref T field, T value, string propertyName)
{
//if the value did not change, do nothing.
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
//the value did change, so make the modification.
field = value;
return true;
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
我现在所做的一切,没有组合框,因为我不知道如何实现组合框来显示 BookContributorType 类中的选择选项:
dataGridView1.DataSource = bookContributors;
感谢您提供的帮助。
这最终比我最初想象的要困难得多。事实证明,如果要使用组合框在 DataGridView 中放置一列,并让该组合框与另一个类交互,则它不是快速的单行代码。
我的例子有两个类:
-
BookContributors
(bookContributors
( - 为一本书做出贡献的人员列表。例如,它存储一个人的姓名和他们所做的贡献类型。 -
BookContributorTypes
(bookContributorTypes
( - 对书籍可能的贡献类型的列表,如编辑或贡献者。 - 我希望
ContributorTypes
类是一个组合框,并将用户的选择存储到BookContributors
类中,特别是BookContributorType
属性。
这是我想出的代码,以及我在此过程中发现的一些其他注释。据我所知,我提供的信息是准确的:-(
gvContributors.DataSource = bookContributors; //set the datgridview's datasource so it displays the class you want.
gvContributors.Columns["BookContributorType"].Visible = false; //hide the column (property) you want to replace with a combobox.
DataGridViewComboBoxColumn contribType = new DataGridViewComboBoxColumn(); //create a combobox object.
contribType.HeaderText = "My Column"; //the text to display in the column header.
contribType.Name = "BookContributorType"; //name of the class property you set to Visible=false. Note sure if this is needed.
contribType.DataSource = bookContributorTypes; //name of the class that provides the combobox data.
contribType.DisplayMember = "BookContributorTypeDescription"; //data the user will see when clicking the combobox.
contribType.ValueMember = "BookContributorTypeId"; //data to store in the class property.
contribType.DataPropertyName = "BookContributorType"; //the class property you are binding to in order to store the data.
gvContributors.Columns.Add(contribType); //add the new combobox to the datagridview.
您现在拥有的是以下内容:
- 具有数据源的
DataGridView
。就我而言,数据源是一个类。 - 要制作组合框的隐藏(
Visible=false
(列。 - 链接到另一个数据源的
DataGridViewComboBox
,以便用户看到值列表。通过将DataPropertyName
用作与隐藏列相同的名称,您现在绑定到 DataGridView 的DataSource
。
这篇文章的另一个答案建议你Remove
用组合框替换的列,但Visible=false
似乎对我有用。
运行解决方案时,您会发现用户必须在组合框上单击两次。我还没有尝试过这段代码,但认为这篇文章会解决这个问题: 单击一下即可打开下拉列表(在数据网格视图中(项目
我在WinForms DataGridView
工作了好几年。AFAIK DataGridView
没有那么聪明如您所料。您必须手动设置 comboBox 列,即在事件DataBindingComplete
- 创建新
DataGridViewComboBoxColumn
- 将其
DataPropertyName
属性设置为"BookContributorType"
- 将其添加到
DataGridViewColumnCollection
- 将其
DataSource
属性设置为BookContributorTypes
集合 - 将其
ValueMember
属性设置为"BookContributorTypeId"
- 将其
DisplayMember
属性设置为"BookContributorTypeDescription"
- 采用自动生成的列中的属性,
BookContributorTypes
如DisplayIndex
- 删除自动生成的列
我正在使用包装类来DataGridView
以获得更智能的控制。通过这种方式,我减少了源代码到处都是我正在使用DataGridView
.
下面是将自动生成的列替换为 comboBox 列的代码片段:
DataGridViewColumn auto // = ... auto-generated column to be replaced
DataGridViewComboBoxColumn combo = new DataGridViewComboBoxColumn();
combo.DataPropertyName = auto.DataPropertyName;
combo.Name = auto.Name;
DataGridView dgv = auto.DataGridView;
dgv.Columns.Add(combo);
combo.DataSource = GetBookContributorTypes; // collection of comboBox entries
combo.ValueMember = "BookContributorTypeId";
combo.DisplayMember = "BookContributorTypeDescription";
// adopt further properties if required
combo.Frozen = auto.Frozen;
combo.DisplayIndex = auto.DisplayIndex;
combo.Visible = auto.Visible;
combo.ReadOnly = auto.ReadOnly;
combo.HeaderText = auto.HeaderText;
combo.HeaderCell.ToolTipText = auto.HeaderCell.ToolTipText;
combo.SortMode = auto.SortMode;
combo.Width = auto.Width;
dgv.Columns.Remove(auto);