DataGridView с перечислениями только устанавливает значение по умолчанию в BindingList
Справочная информация: я создаю простое приложение winform для личного использования для запроса данных, которые я зарегистрировал с помощью XML-сериализации. Эти данные состоят из чемпионов и связанных с ними рас (классов), классов (классов) и т. Д. Моя проблема возникает в пользовательском контроле, предназначенном для добавления новых чемпионов.
Проблема: я использую DataGridViews, чтобы добавить 1 или более Race, Class и т. Д. К новому чемпиону. Каждое из этих свойств является типом enum. Каждый DataGridView привязан к одному типу перечисления, имеющему один столбец со списками для выбора желаемых значений.
Пример DataGridView for Race: (Извините, у меня был скриншот, но мне не хватает представителя.)
[_____ | _ChampRace ________________]
[_.... _ | _Dragon __________________ v_]
[__ * __ | ________________________ v _]
Источник этих DataGridView каждый связан с BindingLists каждого типа перечисления. Когда я выбираю значение в представлении (скажем, ChampRace.Dragon), BindingList получает только добавленное значение по умолчанию (ChampRace.None). Почему список привязок не обновляется по моему желанию?
Пример Enums:
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; }
}
Код UserControl позади:
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, поэтому я надеюсь, что это просто упущенная ошибка.
Наиболее релевантное исследование, которое я нашел, которое привело меня сюда:
1 ответ
Я воссоздал код в тестовой программе и обнаружил, что BindingList ведет себя так, как вы утверждаете. Он хранит список объектов перечисления, но оставляет его при первом перечислении. Так как список привязок, по крайней мере, имеет объект перечисления, я смог использовать событие DataGridView для выполнения обновления данных. В DataGridView есть событие CellValueChanged. Я реализовал событие следующим образом:
private void DataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
this.bindingList[e.RowIndex] = (myEnumeration)DataGridView[e.ColumnIndex, e.RowIndex].Value;
}
Это помещает значение в BindingList с помощью нескольких дополнительных строк кода.