武具の部分を考えてみる
「武具」とはなんぞや、作りたいイメージは前回内容をみてください。
https://qiita.com/puyon/items/698b9f874241c32aa89c
武具たち(武器・イヤリング・手袋・兜・服・靴)には「スロット」が4つづつある。
なので、各武具を4行でひとまとまりな表現にしたい、「セル結合風」表示にしたいと思った。
こぱちゃんに「DataGridViewを使い、セル結合風な表示をしたい」と聞いてみると、そういう機能はないとのこと。それ風な描画で対応するらしい。
あと、データ量が多くなると、「VirtualMode」を使うと、効率よく扱えるようになるらしい。
「VirtualMode」って?
DataGridView でデータというか値を扱う方法に、3パターンあるとのこと。
パターン | 扱うデータ |
---|---|
「Value」プロパティ | セルごとの Value プロパティ |
データバインディング | BindingList |
VirtualMode | データを用意する |
こんな風にすると、VirtualMode を利用するモードになる。
private DataGridView dgv { get; set; }
dgv = new DataGridView();
dgv.VirtualMode = true;
VirtualMode の場合、すべて実装でなんとか用意する必要があるとのこと。
・カラムの設定と行追加
・表示対象データ
・編集結果の格納先
カラムの設定:武具名、ルーン選択、ルーンレベル選択
表示編集対象の「カラム」を全て作成する。
こんな感じ。
DataGridViewTextBoxColumn colArmorName = new DataGridViewTextBoxColumn();
colArmorName.HeaderText = "武具";
colArmorName.Name = "ArmorName";
colArmorName.DataPropertyName = "ArmorName";
colArmorName.ReadOnly = true;
dgv.Columns.Add(colArmorName);
DataGridViewComboBoxColumn colRuneTypeName = new DataGridViewComboBoxColumn();
colRuneTypeName.HeaderText = "ルーン";
colRuneTypeName.Name = "RuneType";
colRuneTypeName.DataPropertyName = "RuneType";
colRuneTypeName.DataSource = runeTypes();
colRuneTypeName.ValueType = typeof(MemeMoriRuneTypes);
dgv.Columns.Add(colRuneTypeName);
武具の行を作成
武具(武器・イヤリング・手袋・兜・服・靴)×「スロット」分の行を作成。
var nRow = 6 * 4;
DataGridViewRow[] rows = new DataGridViewRow[nRow];
for (int i = 0; i < nRow; i++)
{
rows[i] = new DataGridViewRow();
}
dgv.Rows.AddRange(rows);
表示対象データ、編集結果の格納先
あらかじめデータを用意しておき、表示タイミングと編集完了タイミングで、用意したデータをアクセスする。
イベントの登録
dgv.CellValueNeeded += dgv_CellValueNeeded; //表示タイミングでよばれる
dgv.CellValuePushed += dgv_CellValuePushed; //編集完了タイミングでよばれる
イベントの実装(セル単位でのアクセス)
private void dgv_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
//e.Value へ、あらかじめ用意したデータを返す
}
private void dgv_CellValuePushed(object sender, DataGridViewCellValueEventArgs e)
{
//あらかじめ用意したデータへ e.Value を代入
}
武具用クラス作成
クラス表現は、こんな感じ。
/// <summary>
/// キャラ管理:武具セット
/// </summary>
public class MemeMoriArmorSet
{
public Dictionary<MemeMoriArmorTypes, MemeMoriArmorSlot> Armors;
}
/// <summary>
/// キャラ管理:武具スロット
/// </summary>
public class MemeMoriArmorSlot
{
public List<MemeMoriRunePair> Runes { get; set; }
}
/// <summary>
/// キャラ管理:ルーンタイプ・ルーンレベル
/// </summary>
public class MemeMoriRunePair
{
public MemeMoriRuneTypes Type { get; set; }
public MemeMoriRuneLevel Level { get; set; }
}
enum の定義。
/// <summary>
/// ルーン種類
/// </summary>
public enum MemeMoriRuneTypes
{
None = 0, // None(ルーン未装着)
Speed, // Speed(スピード)
Penetration, // Defense Penetration(物魔防御貫通)
Attack, // Attack(攻撃力)
Critical, // Critical(クリティカル)
Strength, // Strength(腕力)
Magic, // Magic(魔力)
Dexterity, // Dexterity(技力)
CriticalResist, // Critical Resistance(クリティカル耐性)
HP, // HP(体力)
PhysicalDefense, // Physical Defense(物理防御)
MagicalDefense, // Magical Defense(魔法防御)
Durability, // Durability(耐久力)
Accuracy, // Accuracy(命中)
DebuffAccuracy, // Debuff Accuracy(弱体効果命中)
Evasion, // Evasion(回避)
DebuffResist, // Debuff Resistance(弱体効果耐性)
RuneMax // End Marker(定義数の最大値)
}
/// <summary>
/// ルーンレベル
/// </summary>
public enum MemeMoriRuneLevel
{
None = 0,
Lv1, Lv2, Lv3, Lv4, Lv5, Lv6, Lv7, Lv8, Lv9
}
/// <summary>
/// ルーン装着先武具
/// 武具 armor 上昇するステータス
/// ----------- ----------- ------------------
/// 武器 weapon 攻撃力
/// イヤリング Earrings 弱体効果耐性
/// 手袋 gloves 防御力
/// 兜 helmet 物理防御力
/// 服 clothes 魔法防御力
/// 靴 shoes 防御力
/// </summary>
public enum MemeMoriArmorTypes
{
Ar1_weapon, Ar2_earrings, Ar3_gloves, Ar4_helmet, Ar5_clothes, Ar6_shoes
}
扱うデータが揃ったので、CellValueNeeded/CellValuePushedイベント内で処理したらいい。