何とかチンチロリンの最終回に漕ぎ付けました。では、最後の部分を見て行きましょう。
(解説(3)からの続き)
/////////////////////
// PlayerViewクラス(解説:PlayerListと似たものですが、これは博徒ファイルを処理します。)
/////////////////////
public class PlayerView : Form
{
//クラスメンバー変数
ListView Player_View; //プレーヤーリスト用リストビュー
ContextMenu contextMenu; //コンテキストメニュー
MenuItem mi0, mi1, mi2, mi3; //コンテキストメニューアイテム
Form dlg; //博徒名入力ダイアログ
TextBox txb; //同上ダイアログの入力テキストボックス
Button btn; //同上ダイアログの「決定」ボタン
public PlayerView()
{
this.ClientSize = new Size(640, 137);
this.BackColor = SystemColors.Window;
this.ShowInTaskbar = false; //タスクバー上表示
this.Left = 580;
this.Top = 110;
this.StartPosition = FormStartPosition.Manual;
this.Text = "Player View";
this.Load += new EventHandler(PlayerView_Load);
}
//WM_CREATE時処理
private void PlayerView_Load(object sender, EventArgs e)
{
//リストビューの生成とプロパティの設定
Player_View = new ListView();
Player_View.Size = new Size(ClientSize.Width - 20, ClientSize.Height - 20); //サイズ
Player_View.Location = new Point(10, 10); //位置
Player_View.Anchor = (AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right);
Player_View.FullRowSelect = true; //一行選択
Player_View.GridLines = true; //グリッドラインの表示
Player_View.MultiSelect = true; //複数選択を許す
Player_View.Activation = ItemActivation.OneClick; //シングルクリック選択
Player_View.CheckBoxes = false; //チェックボックス無効化
Player_View.View = View.Details; //リストビューの表示方法
Player_View.Scrollable = true; //スクロールバーを表示
//イベントハンドラの追加
Player_View.ColumnClick += new ColumnClickEventHandler(OnLV_ColumnClick);
//ヘッダー定義
Player_View.Columns.Add("博徒ファイル名", 152, HorizontalAlignment.Left);
Player_View.Columns.Add("破産", 48, HorizontalAlignment.Center);
Player_View.Columns.Add("所持金", 120, HorizontalAlignment.Center);
Player_View.Columns.Add("運", 48, HorizontalAlignment.Center);
Player_View.Columns.Add("強気", 48, HorizontalAlignment.Center);
Player_View.Columns.Add("累計勝負数", 120, HorizontalAlignment.Center);
Player_View.Columns.Add("累計勝数", 80, HorizontalAlignment.Center);
Player_View.Columns.Add("累計負数", 80, HorizontalAlignment.Center);
Player_View.Columns.Add("累計勝率", 80, HorizontalAlignment.Center);
//コンテキストメニュー関連
mi0 = new MenuItem();
mi0.Index = 0;
mi0.Text = "博徒ファイルの新規作成";
mi1 = new MenuItem();
mi1.Index = 0;
mi1.Text = "博徒ファイルの読み込み";
mi2 = new MenuItem();
mi2.Index = 0;
mi2.Text = "博徒ファイルの削除";
mi3 = new MenuItem();
mi3.Index = 0;
mi3.Text = "終了";
contextMenu = new ContextMenu();
contextMenu.MenuItems.Add(mi0);
contextMenu.MenuItems.Add(mi1);
contextMenu.MenuItems.Add(mi2);
contextMenu.MenuItems.Add("-"); //セパレーター
contextMenu.MenuItems.Add(mi3);
Player_View.ContextMenu = contextMenu;
mi0.Click += new EventHandler(Make_Player);
mi1.Click += new EventHandler(Read_Players);
mi2.Click += new EventHandler(Del_Player);
mi3.Click += new EventHandler(Done);
//FormにListViewを追加
this.Controls.Add(Player_View);
//初期的に博徒ファイルを読み込む
Read_Players(this, new EventArgs());
}
//Player_Viewのコラムがクリックされた時
private void OnLV_ColumnClick(object sender, ColumnClickEventArgs e)
{
//ListViewItemSorterを指定する
Player_View.ListViewItemSorter = new ListViewItemComparer(e.Column);
//正順、逆順交互に並び替える(ListViewItemSorterを設定するとSortが自動的に呼び出される)
}
//「博徒ファイルの新規作成」処理
public void Make_Player(object sender, EventArgs e)
{
//入力ダイアログを作る
dlg = new Form();
dlg.FormBorderStyle = FormBorderStyle.FixedSingle; //サイズの変更を不可にする
dlg.Size = new Size(240, 120);
dlg.StartPosition = FormStartPosition.CenterParent;
dlg.Text = "博徒名の入力";
Label lbl = new Label();
lbl.Size = new Size(200, 18);
lbl.Location = new Point(10, 10);
lbl.Text = "博徒名を入力してください。";
dlg.Controls.Add(lbl);
txb = new TextBox();
txb.Size = new Size(200, 24);
txb.Location = new Point(10, lbl.Height + 10);
txb.Text = "(博徒名)";
dlg.Controls.Add(txb);
btn = new Button();
btn.Size = new Size(48, 24);
btn.Location = new Point(dlg.Width / 2 - 24, lbl.Height + txb.Height + 20);
btn.Text = "決定";
btn.Click += new EventHandler(btn_Click);
dlg.Controls.Add(btn);
dlg.ShowDialog(this); //解説:ダイアログをShowDialogで表示したら最後にDIspose()しなくてはなりません。
}
//「博徒ファイルの新規作成」の名前入力ダイアログの処理
public void btn_Click(object sender, EventArgs e)
{
if(txb.Text == "" || txb.Text == "(博徒名)")
{
MessageBox.Show("博徒の名前を正しく入力してください。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
//Playerクラスインスタンスを作成、datファイルを書き込む
Player pl = new Player(txb.Text);
pl.FinalRecord();
//博徒ファイルを再度読み込む
GetDataFiles();
//博徒名入力ダイアログを開放する
dlg.Dispose();
}
}
//「博徒ファイルの読み込み」処理
public void Read_Players(object sender, EventArgs e)
{
//Playersフォールダーのデータファイルを読む
GetDataFiles();
}
//「博徒ファイルの削除」処理
public void Del_Player(object sender, EventArgs e)
{
if(Player_View.SelectedItems.Count < 1)
{
MessageBox.Show("削除する博徒名ファイルが未選択です。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
foreach(ListViewItem item in Player_View.SelectedItems)
{
DialogResult dr = MessageBox.Show("博徒" + item.Text + "ファイルを削除しますか?", "確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if(dr == DialogResult.Yes)
{
//選択された博徒ファイルを削除
File.Delete(".\\Players\\" + item.Text); //ファイル削除
item.Remove(); //リストビューから削除
}
}
}
}
//「終了」処理
public void Done(object sender, EventArgs e)
{
Close();
}
//Playersフォールダーの*.datファイルを取得
public void GetDataFiles()
{
//ListViewのデータをクリアする
Player_View.Items.Clear();
//Playersフォールダーの*.datファイルを表示
IEnumerable<string> files = null;
files = Directory.EnumerateFiles(".\\Players", "*.dat", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
string fn = file.Replace(".\\Players\\", "");
Player pl = new Player(fn.Replace(".dat", ""));
ListViewItem item = Player_View.Items.Add(fn);
item.SubItems.Add(pl.IsBankrupt.ToString());
item.SubItems.Add(String.Format("{0:C}", pl.Capital));
item.SubItems.Add(pl.Luck.ToString());
item.SubItems.Add(pl.BullBear.ToString());
item.SubItems.Add(String.Format("{0:#,0}", pl.TotalGames));
item.SubItems.Add(String.Format("{0:#,0}", pl.TotalWins));
item.SubItems.Add(String.Format("{0:#,0}", pl.TotalLoses));
if(pl.TotalGames > 0)
{
double rate = (double)pl.TotalWins / (double)pl.TotalGames;
item.SubItems.Add(String.Format("{0:P3}", rate));
}
else
item.SubItems.Add("N/A");
}
}
}
///////////////////////////////////////////
//ListViewの項目の並び替えに使用するクラス(解説:PlayerList、PlayerView共通)
///////////////////////////////////////////
public class ListViewItemComparer : IComparer
{
private int m_column;
private static int m_order = 1; //毎回呼ばれるたびに正順、逆順を交代させるフラグ
//ListViewItemComparerクラスのコンストラクタ
public ListViewItemComparer(int col)
{
m_column = col;
m_order *= -1; //ListViewItemComparerが呼ばれる度に正順、逆順が変更される
}
//xがyより小さいときはマイナスの数、大きいときはプラスの数、同じときは0を返す
public int Compare(object x, object y)
{
//ListViewItemの取得
ListViewItem itemx = (ListViewItem) x;
ListViewItem itemy = (ListViewItem) y;
//xとyを文字列として比較する
return string.Compare(itemx.SubItems[m_column].Text, itemy.SubItems[m_column].Text) * m_order;
}
}
//////////////////////
//InputBet ダイアログ
//////////////////////
public class InputBetDlg : Form
{
//クラスメンバープロパティ・変数
public int Bet {get; private set;} //賭金
int Max; //Playerの所持金残高
ComboBox BetList;
public InputBetDlg(Icon ico, Player pl) //icoは親のアイコンを承継する。plはPlayerクラス
{
//ダイアログの属性設定
this.Text = "賭金設定";
this.ClientSize = new Size(320, 214);
this.MaximizeBox = false; // 最大化ボタン
this.MinimizeBox = false; // 最小化ボタン
this.ShowInTaskbar = false; //タスクバー上表示
this.FormBorderStyle = FormBorderStyle.FixedDialog; // 境界のスタイル
this.StartPosition = FormStartPosition.CenterParent; // 親フォームの中央に配置
//所持金確認と賭金初期設定
Max = pl.Capital;
Bet = pl.Bet();
//コントロール設定
//アイコン表示用ラベル
Label imglabel = new Label();
imglabel.Size = new Size(40, 40);
imglabel.Location = new Point(10, 10);
imglabel.BorderStyle = BorderStyle.Fixed3D;
imglabel.Image = ico.ToBitmap(); //親のシステムアイコン
this.Controls.Add(imglabel);
//スタッツ表示用ラベル
Label label1 = new Label();
label1.Size = new Size(ClientSize.Width - imglabel.Width - 30, 18);
label1.Location = new Point(imglabel.Width + 20, 10);
label1.BorderStyle = BorderStyle.Fixed3D;
label1.Text = "今回の勝負数\t:" + pl.ThisGames.ToString();
label1.TextAlign = ContentAlignment.MiddleLeft;
Label label2 = new Label();
label2.Size = new Size(ClientSize.Width - imglabel.Width - 30, 18);
label2.Location = new Point(imglabel.Width + 20, label1.Size.Height + 20);
label2.BorderStyle = BorderStyle.Fixed3D;
label2.Text = "今回の勝数\t:" + pl.ThisWins.ToString();
label2.TextAlign = ContentAlignment.MiddleLeft;
Label label3 = new Label();
label3.Size = new Size(ClientSize.Width - imglabel.Width - 30, 18);
label3.Location = new Point(imglabel.Width + 20, label1.Size.Height + label2.Size.Height + 30);
label3.BorderStyle = BorderStyle.Fixed3D;
label3.Text = "今回の負数\t:" + pl.ThisLoses.ToString();
label3.TextAlign = ContentAlignment.MiddleLeft;
Label label4 = new Label();
label4.Size = new Size(ClientSize.Width - imglabel.Width - 30, 18);
label4.Location = new Point(imglabel.Width + 20, label1.Size.Height + label2.Size.Height + label3.Size.Height + 40);
label4.BorderStyle = BorderStyle.Fixed3D;
label4.Text = "現在の所持金\t:" + String.Format("{0:C}", pl.Capital);
label4.ForeColor = Color.Red; //注意の為に赤字にする
label4.TextAlign = ContentAlignment.MiddleLeft;
Label label5 = new Label();
label5.Size = new Size(ClientSize.Width - imglabel.Width - 30, 18);
label5.Location = new Point(imglabel.Width + 20, label1.Size.Height + label2.Size.Height + label3.Size.Height + label3.Size.Height + 50);
label5.BorderStyle = BorderStyle.Fixed3D;
label5.Text = "PCの推奨賭金\t:" + String.Format("{0:C}", Bet);
label5.ForeColor = Color.Blue; //注意の為に青字にする
label5.TextAlign = ContentAlignment.MiddleLeft;
this.Controls.Add(label1);
this.Controls.Add(label2);
this.Controls.Add(label3);
this.Controls.Add(label4);
this.Controls.Add(label5);
//賭金入力コンボボックス
BetList = new ComboBox();
BetList.Size = new Size(ClientSize.Width - imglabel.Width - 30, 24);
BetList.Location = new Point(imglabel.Width + 20, label1.Size.Height + label2.Size.Height + label3.Size.Height + label4.Size.Height + label5.Size.Height + 60);
BetList.DropDownStyle = ComboBoxStyle.DropDownList; //勝手な金額の入力はできない
BetList.Text = String.Format("{0:C}", Bet);
for(int i = 1; i <= 20; i++) //1000円単位賭金リスト
{
BetList.Items.Add(String.Format("{0:C}", i * 1000));
}
this.Controls.Add(BetList);
//決定ボタン
Button btnOK = new Button();
btnOK.Size = new Size(54, 28);
btnOK.Location = new Point(ClientSize.Width - btnOK.Width - 10, ClientSize.Height - btnOK.Height - 10);
btnOK.Text = "決定";
btnOK.Click += new EventHandler(OnOK_Click);
this.Controls.Add(btnOK);
}
private void OnOK_Click(object sender, EventArgs e)
{
//賭金コンボボックスが選択されたならその金額、そうでなければpl.Bet()のままとなる
if(BetList.SelectedIndex > -1)
{
Bet = (BetList.SelectedIndex + 1) * 1000;
if(Bet > Max)
{
MessageBox.Show("選択金額が所持金を超えたので所持金以内とします。", "警告", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
Bet = (Max / 1000) * 1000; //千円単位端数切り捨て
}
}
else
MessageBox.Show("金額が選択されなかったので、賭金はPCの推奨する" + String.Format("{0:C}", Bet) + "とします。", "確認", MessageBoxButtons.OK, MessageBoxIcon.Question);
Close();
}
}
/////////////////////
//Version ダイアログ
/////////////////////
public class VersionDlg : Form
{
public VersionDlg(Icon ico)
{
//ダイアログの属性設定
this.Text = "バーション情報";
this.ClientSize = new Size(320, 100);
this.MaximizeBox = false; // 最大化ボタン
this.MinimizeBox = false; // 最小化ボタン
this.ShowInTaskbar = false; //タスクバー上表示
this.FormBorderStyle = FormBorderStyle.FixedDialog; // 境界のスタイル
this.StartPosition = FormStartPosition.CenterParent; // 親フォームの中央に配置
//コントロールの属性設定
Button btnOK = new Button();
btnOK.Size = new Size(40, 28);
btnOK.Location = new Point(ClientSize.Width - btnOK.Width - 10, (ClientSize.Height - btnOK.Height) / 2);
btnOK.Text = "OK";
btnOK.Click += new EventHandler(OnOK_Click);
Label imglabel = new Label();
imglabel.Size = new Size(40, 40);
imglabel.Location = new Point(10, (ClientSize.Height - imglabel.Height) / 2);
imglabel.BorderStyle = BorderStyle.Fixed3D;
imglabel.Image = ico.ToBitmap(); //親のシステムアイコン
Label label = new Label();
label.Size = new Size(ClientSize.Width - imglabel.Width - btnOK.Width - 40, ClientSize.Height- 20);
label.Location = new Point(imglabel.Width + 20, (ClientSize.Height - label.Height) / 2);
label.BorderStyle = BorderStyle.Fixed3D;
label.Text = "Chinchirorin Version 1.0\r\nCopyright (c) 2023 by Ysama\r\n";
label.TextAlign = ContentAlignment.MiddleCenter;
label.Font = new Font("Times New Roman", 10, FontStyle.Bold);
this.Controls.Add(btnOK);
this.Controls.Add(imglabel);
this.Controls.Add(label);
}
private void OnOK_Click(object sender, EventArgs e)
{
Close();
}
}
}
以上です。あともう一回だけ、コンパイルと使い勝手等について解説をしようかと思います。
あ"~、疲れた。
なお、WPFとの悪戦苦闘も終わりました。次のネタにしますので、ご期待ください。














