C# 带有枚举的DataGridView仅在BindingList中设置默认值
背景:我正在创建一个简单的winform应用程序,供个人使用,用于查询通过XML序列化记录的数据。这些数据包括冠军及其相关的种族(es)、职业(es)等。我的问题发生在一个旨在添加新冠军的用户控件中 问题:我正在使用DataGridView向新冠军添加一个或多个种族、职业等。每个属性都是枚举类型。每个DataGridView绑定到一个枚举类型,有一列组合框来选择所需的值 Race的DataGridView示例: (对不起,我有截图,但没有足够的代表。) [冠军赛,冠军赛] […..124;龙uuuuuuuuuuuuuuuuuuuuuuuuuv_uuuu] [\uuu*\ uu124; uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuv] 这些DataGridView的源都绑定到每种枚举类型的绑定列表。当我在视图中选择一个值(比如ChampRace.Dragon)时,BindingList只接收默认的附加值(ChampRace.None)。为什么绑定列表没有按照我的要求更新 示例枚举:C# 带有枚举的DataGridView仅在BindingList中设置默认值,c#,winforms,datagridview,enums,bindinglist,C#,Winforms,Datagridview,Enums,Bindinglist,背景:我正在创建一个简单的winform应用程序,供个人使用,用于查询通过XML序列化记录的数据。这些数据包括冠军及其相关的种族(es)、职业(es)等。我的问题发生在一个旨在添加新冠军的用户控件中 问题:我正在使用DataGridView向新冠军添加一个或多个种族、职业等。每个属性都是枚举类型。每个DataGridView绑定到一个枚举类型,有一列组合框来选择所需的值 Race的DataGridView示例: (对不起,我有截图,但没有足够的代表。) [冠军赛,冠军赛] […..124;龙uu
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; }
}
公开课冠军
{
[XmlAttribute]
公共字符串名称{get;set;}
[XmlElement]
公共列表竞赛{get;set;}
[XmlElement]
公共列表类{get;set;}
[XmlElement]
公共列表派系{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);
}
}
公共部分类NewChampion:UserControl
{
公众新冠军()
{
this.InitializeComponent();
这是.InitializeAllData();
}
公共主控主机{get;set;}
公共绑定列表{get;set;}
公共绑定列表类{get;set;}
公共绑定列表派系{get;set;}
私有void AddChampionButton_单击(对象发送者,事件参数e)
{
冠军=新冠军();
champion.Name=this.nameTextBox.Text;
champion.Classes=新列表();
champion.派系=新列表();
champion.Races=新列表();
foreach(本.Classes中的ChampClass cc)
{
champion.Classes.Add(cc);
}
foreach(本次比赛中的ChampRace cr)
{
冠军。比赛。添加(cr);
}
foreach(本章中的f派系。派系)
{
冠军。派系。添加(f);
}
System.Diagnostics.Debug.WriteLine(“调试过程中的断点用于验证数据…”);
//注意:根据屏幕截图,这个.Races有一个值。
//与预期值“Dragon”不同,该值始终为“None”。
}
private void InitializeAllData()
{
this.Races=newbindingslist();
this.Classes=newbindingList();
this.派系=新绑定列表();
/*
*添加了以下事件处理程序以在dgView中显示新的可编辑行。
*没有它们,就不会出现行。
*/
this.Classes.AddingNew+=(s,e)=>
{
//e.NewObject=ChampClass.None;
};
this.Races.AddingNew+=(s,e)=>
{
//e.NewObject=ChampRace.None;
};
this.particles.AddingNew+=(s,e)=>
{
//e.NewObject=派系。无;
};
this.raceData.DataSource=this.Races;
this.classData.DataSource=this.Classes;
this.派系数据源=this.派系;
此.SetupDataOptions(参考此.raceData);
this.SetupDataOptions(参考this.classData);
this.SetupDataOptions(参考此.SetupDataOptions);
}
私有void SetupDataOptions(参考DataGridView数据)
其中T:struct,i可比较,i可附加,i可转换
{
if(!typeof(T).IsEnum)
{
抛出新ArgumentException(“类型必须是枚举”);
}
DataGridViewComboBoxColumn组合=新建DataGridViewComboxColumn();
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(组合);
}
}
这是我第一次使用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中,只需要额外的几行代码