コンテキストメニューをインターフェースに合わせて切り替え表示
MyDummySQLProに、ショートカットメニューをつけてみました。
主に、テキストボックスに入っているスクリプトをテンプレートに保存するためのメニュー項目をつけたかったからです。
AccessSavableTextBoxは継承させたかったので、またまたインターフェースでクラス(オブジェクト)を識別認識させています。
IHasCategorizedTextAndContextMenuインターフェースを実装したテキストボックス:TextBoxForTemplate
namespace MyDummySQL.ControlsForTemplate
{
public class TextBoxForTemplate : AccessSavableTextBox, IHasCategorizedTextAndContextMenu
{
private string categoryName = "dummy";
public string CategoryName {
get
{
if (this.Parent != null && "dummy".Equals(this.categoryName))
{
return this.Parent.Text;
}
return this.categoryName;
}
set
{
this.categoryName = value;
}
}
public TextBoxForTemplate()
: base()
{
this.ContextMenuStrip = (new ContextMenuBuilderFactory()).Create(this).Build();
}
public TextBoxForTemplate(string categoryName) : base()
{
this.categoryName = categoryName;
this.ContextMenuStrip = (new ContextMenuBuilderFactory()).Create(this).Build();
}
}
}
今回インターフェイスは2種あります。
一つ目、ふつうの「コピー」「切り取り」「貼り付け」しかないコンテキストメニューを表示させるテキストボックス用:IHasTextAndContextMenu
namespace MyDummySQL.ControlsForTemplate
{
public interface IHasTextAndContextMenu
{
string Text { get; set; }
string SelectedText { get; set; }
//System.Windows.Forms.ContextMenuStrip ContextMenuStrip { get; set; }
}
}
二つ目、一つ目のメニューに加えて「テンプレートに保存」「テンプレートから取得」のメニュー項目も表示するテキストボックス用:
namespace MyDummySQL.ControlsForTemplate
{
public interface IHasCategorizedTextAndContextMenu : IHasTextAndContextMenu
{
string CategoryName { get; set; }
}
}
次に、メニューを作成するクラスを、インターフェースで切り替え生成するファクトリ:ContextMenuBuilderFactory
namespace MyDummySQL.ControlsForTemplate
{
public class ContextMenuBuilderFactory
{
public ContextMenuBuilderFactory() { }
public ContextMenuBuilder Create(IHasTextAndContextMenu control)
{
return new ContextMenuBuilder(control);
}
public ContextMenuBuilder Create(IHasCategorizedTextAndContextMenu control)
{
return new ContextMenuBuilderWidthCategory(control);
}
}
}
次に実際に普通のメニューを作成する”自称ビルダー”(注:ビルダーパターンではないです):ContextMenuBuilder
namespace MyDummySQL.ControlsForTemplate
{
public class ContextMenuBuilder
{
//ContextMenu
protected ContextMenuStrip cMenu = new ContextMenuStrip();
protected IHasTextAndContextMenu HasText = null;
public ContextMenuBuilder(IHasTextAndContextMenu control)
{
this.HasText = control;
}
virtual public ContextMenuStrip Build()
{
//this.HasText = control;
/*
this.BuildCopy();
this.BuildCut();
this.BuildPaste();
*/
this.BuildBasicMenu();
return this.cMenu;
}
private void BuildBasicMenu()
{
this.BuildCopy();
this.BuildCut();
this.BuildPaste();
}
virtual protected void BuildCopy()
{
//Copy
ToolStripMenuItem mCopy = new ToolStripMenuItem();
mCopy.Text = "コピー(&C)";
mCopy.Click += delegate
{
if (!string.IsNullOrEmpty(this.HasText.SelectedText))
{
Clipboard.SetText(this.HasText.SelectedText);
}
else if (!string.IsNullOrEmpty(this.HasText.Text))
{
Clipboard.SetText(this.HasText.Text);
}
};
this.cMenu.Items.Add(mCopy);
}
virtual protected void BuildCut()
{
//Cut
ToolStripMenuItem mCut = new ToolStripMenuItem();
mCut.Text = "切り取り(&X)";
mCut.Click += delegate
{
if (!string.IsNullOrEmpty(this.HasText.SelectedText))
{
Clipboard.SetText(this.HasText.SelectedText);
this.HasText.SelectedText = "";
}
else if (!string.IsNullOrEmpty(this.HasText.Text))
{
Clipboard.SetText(this.HasText.Text);
this.HasText.Text = "";
}
};
this.cMenu.Items.Add(mCut);
}
virtual protected void BuildPaste()
{
//Paste
ToolStripMenuItem mPaste = new ToolStripMenuItem();
mPaste.Text = "貼り付け(&V)";
mPaste.Click += delegate
{
if (!string.IsNullOrEmpty(this.HasText.SelectedText))
{
this.HasText.SelectedText = Clipboard.GetText();
}
else
{
this.HasText.Text = Clipboard.GetText();
}
};
cMenu.Items.Add(mPaste);
}
}
}
さらに上のクラスを継承して、「テンプレートに保存」「テンプレートから取得」メニューを追加する”自称ビルダー”:ContextMenuBuilder
(ただし、テンプレート保存・取得の実装プログラムはまだ作っていませんので、仮です)
namespace MyDummySQL.ControlsForTemplate
{
public class ContextMenuBuilderWidthCategory : ContextMenuBuilder
{
//private IHasCategorizedTextAndContextMenu HasCategorizedText = null;
public ContextMenuBuilderWidthCategory(IHasCategorizedTextAndContextMenu control)
: base(control)
{
this.HasText = control;
}
public override ContextMenuStrip Build()
{
this.cMenu = base.Build();
BuildAddToTemplate();
BuildGetFromTemplate();
return this.cMenu;
}
virtual public void BuildAddToTemplate()
{
//Copy
ToolStripMenuItem mToTemp = new ToolStripMenuItem();
mToTemp.Text = "テンプレートに保存(&T)";
mToTemp.Click += delegate
{
string template = string.Empty;
string category = string.Empty;
if (!string.IsNullOrEmpty(this.HasText.SelectedText))
{
template = this.HasText.SelectedText;
}
else if (!string.IsNullOrEmpty(this.HasText.Text))
{
template = this.HasText.Text;
}
IHasCategorizedTextAndContextMenu obj = this.HasText as IHasCategorizedTextAndContextMenu;
if (obj != null)
{
category = obj.CategoryName;
}
frmAddTemplates addFrm = new frmAddTemplates(category, template);
addFrm.Show();
};
this.cMenu.Items.Add(mToTemp);
}
virtual public void BuildGetFromTemplate()
{
//Copy
ToolStripMenuItem mFromTemp = new ToolStripMenuItem();
mFromTemp.Text = "テンプレートから取得(&G)";
mFromTemp.Click += delegate
{
string template = string.Empty;
string category = string.Empty;
if (!string.IsNullOrEmpty(this.HasText.SelectedText))
{
template = this.HasText.SelectedText;
}
else if (!string.IsNullOrEmpty(this.HasText.Text))
{
template = this.HasText.Text;
}
IHasCategorizedTextAndContextMenu obj = this.HasText as IHasCategorizedTextAndContextMenu;
if (obj != null)
{
category = obj.CategoryName;
}
frmTemplates frmTemp = new frmTemplates();
frmTemp.Show();
};
this.cMenu.Items.Add(mFromTemp);
}
}
}
テンプレート関連を扱うフォームは以下のような感じです。
・・・つ、疲れた。また来週〜。


