带枚举的 DataGridView 仅在 BindingList 中设置默认值
本文关键字:设置 默认值 BindingList 仅在 枚举 DataGridView | 更新日期: 2023-09-27 18:32:32
>背景:我正在创建一个简单的winform 应用程序供个人使用,以查询我通过XML序列化记录的数据。 这些数据包括英雄及其相关的种族、职业等。 我的问题发生在旨在添加新冠军的用户控件中。
问题:我正在使用 DataGridViews 向新英雄添加 1 个或多个种族、职业等。 其中每个属性都是枚举类型。 每个 DataGridView 都绑定到一个枚举类型,具有一列组合框来选择所需的值。
种族数据网格视图示例:(抱歉,我有屏幕截图,但没有足够的代表。
[__|_ChampRace________________]
[_ .... _|_Dragon__________________v_]
[__* __|____
这些 DataGridView 的源都绑定到每个枚举类型的 BindingLists。当我在视图中选择一个值(比如ChampRace.Dragon(时,BindingList只接收默认的附加值(ChampRace.None(。为什么绑定列表没有按照我的意愿更新?
示例枚举:
public enum ChampRace
{
None,
Angel,
Beast,
Dragon,
Etc
}
序列化类:
public class Champion
{
[XmlAttribute]
public string Name { get; set; }
[XmlElement]
public List<ChampRace> Races { get; set; }
[XmlElement]
public List<ChampClass> Classes { get; set; }
[XmlElement]
public List<Faction> Factions { get; set; }
}
用户控件代码隐藏:
public partial class NewChampion : UserControl
{
public NewChampion()
{
this.InitializeComponent();
this.InitializeAllData();
}
public Master Master { get; set; }
public BindingList<ChampRace> Races { get; set; }
public BindingList<ChampClass> Classes { get; set; }
public BindingList<Faction> Factions { get; set; }
private void AddChampionButton_Click(object sender, EventArgs e)
{
Champion champion = new Champion();
champion.Name = this.nameTextBox.Text;
champion.Classes = new List<ChampClass>();
champion.Factions = new List<Faction>();
champion.Races = new List<ChampRace>();
foreach (ChampClass cc in this.Classes)
{
champion.Classes.Add(cc);
}
foreach (ChampRace cr in this.Races)
{
champion.Races.Add(cr);
}
foreach (Faction f in this.Factions)
{
champion.Factions.Add(f);
}
System.Diagnostics.Debug.WriteLine("Break point here during debug to verify data...");
// Note: At this point based on the screenshot, this.Races has one value.
// Instead of the expected value "Dragon", the value is always "None".
}
private void InitializeAllData()
{
this.Races = new BindingList<ChampRace>();
this.Classes = new BindingList<ChampClass>();
this.Factions = new BindingList<Faction>();
/*
* The following event handlers were added to show a new editable row in the dgView.
* Without them, no rows appear.
*/
this.Classes.AddingNew += (s, e) =>
{
// e.NewObject = ChampClass.None;
};
this.Races.AddingNew += (s, e) =>
{
// e.NewObject = ChampRace.None;
};
this.Factions.AddingNew += (s, e) =>
{
// e.NewObject = Faction.None;
};
this.raceData.DataSource = this.Races;
this.classData.DataSource = this.Classes;
this.factionData.DataSource = this.Factions;
this.SetupDataOptions<ChampRace>(ref this.raceData);
this.SetupDataOptions<ChampClass>(ref this.classData);
this.SetupDataOptions<Faction>(ref this.factionData);
}
private void SetupDataOptions<T>(ref DataGridView data)
where T : struct, IComparable, IFormattable, IConvertible
{
if (!typeof(T).IsEnum)
{
throw new ArgumentException("Type must be an enumeration");
}
DataGridViewComboBoxColumn combo = new DataGridViewComboBoxColumn();
combo.ValueType = typeof(T);
combo.DataSource = Enum.GetValues(typeof(T));
combo.DataPropertyName = typeof(T).ToString();
combo.Name = typeof(T).ToString().Split('.').Last();
data.AutoGenerateColumns = false;
data.AutoSize = true;
data.Columns.Add(combo);
}
}
这是我第一次使用 DataGridViews 和 BindingLists,所以我希望这是一个容易被忽视的错误。
我发现的最相关的研究让我来到这里:
- 如果值是枚举,则组合框不会设置默认值
- 使 DataGridView 列在绑定到绑定列表后可编辑
- DataGridView 不更新 BindingList 中的枚举
- 组合框列上的数据网格视图默认错误
我在测试程序中重新创建了代码,发现 BindingList 的行为与您所说的一样。 它保留枚举对象的列表,但将其保留在第一个枚举处。 由于绑定列表至少有一个枚举对象,因此我能够使用 DataGridView 事件来完成数据更新。 在 DataGridView 中,有一个事件 CellValueChanged。 我按如下方式实现了该事件:
private void DataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
this.bindingList[e.RowIndex] = (myEnumeration)DataGridView[e.ColumnIndex, e.RowIndex].Value;
}
这会将值放在 BindingList 中,只需多写几行代码。