WPF_Delegateとコールバック操作
delegate
デリゲートとは
C#のデリゲートは、関数を入れることができる変数(データ型)です。
delegate 戻り値の型 デリゲート型名(引数リスト);
代入することでメソッドを割り当てます。
using System;
namespace LogicTest
{
class Program
{
public delegate void Deleg(String str);
static void Main(string[] args)
{
// Deleg1にメソッド execute1 を割り当てる
Deleg Deleg1 = new Deleg(execute1);
// Deleg1を実行することで、実際には execute1 が実行される
Deleg1("Deleg1");
// メソッドはnewなしでも割り当てられる
Deleg Deleg2 = execute1;
Deleg2("Deleg2");
// 複数メソッドを割り当てることができます
Deleg2 += new Deleg(execute2);
Deleg2("Deleg2");
}
public void execute1(string str1)
{
System.Console.WriteLine("execute1() is called by " + str1);
}
public void execute2(string str1)
{
System.Console.WriteLine("execute2() is called by " + str1);
}
}
}
コールバック処理
delegateにメソッドを代入して、処理完了の契機でコールバックメソッドを実行することは、頻繁に利用する手法です。
public delegate void Callback(string msg);
public void Main(string[] args)
{
Execute(OutputMessage);
}
public void Execute(Callback callback)
{
System.Console.WriteLine("Execute(): start");
Thread.Sleep(2000);
callback("Execute callback!");
System.Console.WriteLine("Execute(): finish");
}
public void OutputMessage(string msg)
{
System.Console.WriteLine("OutputMessage(): " + msg);
}
FuncとAction
FuncとActionの違い
デリゲートの形式をいちいち宣言することが手間である場合、Func/Actionが利用できます。
Funcは下記のように定義した場合、delegateMethodに「intの引数を1つとり、intの値を返す」処理を登録することができます。
Func<int, int> delegateMethod
Actionは下記のように定義した場合、delegateMethodに「int 型の引数を2つとる」処理を登録することができます。
Action<int, int> delegateMethod
簡単にいえば、返り値が無い場合がAction、返り値が有る場合が Funcです。
//引数がstring
Action<string> action1;
//引数がstringとint
Action<string, int> action2;
//返り値がint
Func<int> func1;
//引数がstring、返り値がint
Func<string, int> func2;
Funcのコールバック処理例
メソッドの引数にコールバックメソッドをセットし、任意に実行します。
public void Main(string[] args)
{
bool rc = Execute(OutputMessage);
}
public bool Execute(Func<string, bool> callback)
{
System.Console.WriteLine("Execute(): start");
Thread.Sleep(2000);
// コールバックを実行する。
bool rc = callback("Execute callback!");
System.Console.WriteLine("Execute(): finish");
return rc;
}
public bool OutputMessage(string msg)
{
try
{
System.Console.WriteLine("OutputMessage(): " + msg);
return true;
}
catch (Exception ex)
{
System.Console.WriteLine(ex.Message);
return false;
}
}
event
eventは、delegate専用の修飾語になります。
eventキーワードを使用すると、外部から代入と実行はできなくなります。
「これ使って」と渡すのがDelegateであり、「こちらで使うから登録して」とするのがEventとなります。
class MyClass
{
public Action<string> Delegate; // delegate
public event Action<string> Event; // event
// Event実行用の公開メソッド
public void ExecEventMethod(string txt)
{
// 下記の記載で if (Event != null) { Event(txt); }と同じ意味となる。
Event?.Invoke(txt);
}
}
private void WriteMsg(string msg)
{
BindText += msg;
BindText += Environment.NewLine;
}
public void Main()
{
var my = new MyClass();
// delegateの場合
my.Delegate = WriteMsg;
my.Delegate += WriteMsg;
my.Delegate -= WriteMsg;
my.Delegate("Execute Delegate Method");
// eventの場合
// my.Event = WriteMsg; // エラー
my.Event += WriteMsg;
my.Event -= WriteMsg;
//my.Event("Execute Event Method"); // エラー
// eventの登録メソッドを実行する場合は、MyClassから呼び出す口を用意する。
my.Event += WriteMsg;
my.ExecEventMethod("Execute Event Method");
}
関連ページ
- WPF_Prism_BindableBase
- WPF_Prism_DelegateCommand
- WPF_Prism_InteractionRequest
- WPF_Prism_CompositeCommand
- WPF_Prism_ErrorsContainer
- WPF_Prism_InvokeCommandAction
- C#