FC2ブログ

コマンドクラスのリメイク(四)

コマンドクラスのリメイク(壱)
コマンドクラスのリメイク(弐)
コマンドクラスのリメイク(参)
の続き

・同期型コマンドクラス
短時間で終わる処理に向いている。非同期より構造が簡単なので処理は速い(と思う)。
〇クラス宣言
/// <summary>
/// 同期型コマンド用クラス
/// </summary>
public class DelegateCommand : CommandExBase {

〇実行メソッド
/// <summary>
/// コマンド実行
/// </summary>
/// <param name="parameter">コマンドパラメータ</param>
protected override void ExecuteProtected(object parameter) {
try {
if (!this.NeedSync) {
//Dispatcher.Invokeを使うと、むしろエラーになる時の回避策
this.ExecuteAction(parameter);
} else if (this.Dispatcher.Thread == System.Threading.Thread.CurrentThread) {
this.ExecuteAction(parameter);
} else {
this.Dispatcher.Invoke(this.ExecuteAction, this.Priority, parameter);
}

//先にフラグをOFF
this.NowExecuting = false;
//実行完了後のアクション
this.CompletedExecuteAction?.Invoke(this, null);

} catch (Exception ex) {
//先にフラグをOFF
this.NowExecuting = false;
//実行完了後のアクション
this.CompletedExecuteAction?.Invoke(this, ex);
}

return;
}
CompletedExecuteActionを呼び出す前にNowExecutingをfalseにしないと、CanExecute再評価で困る事になる。続きを読む
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0

コマンドクラスのリメイク(参)

コマンドクラスのリメイク(壱)
コマンドクラスのリメイク(弐)
の続き。長くなってしまった。
・汎用抽象クラス
 同期、非同期に依存しない共通部分を汎用クラス化。実装が分かれる部分を抽象メソッドとしている。実行処理本体以外は、そんなに違わない。
〇クラス宣言
namespace Tawamuredays.Commands {

using Tawamuredays.Data;

/// <summary>
/// コマンド用 基底クラス
/// </summary>
/// <remarks>
public abstract class CommandExBase : ICommandEx {

汎用クラスのインスタンスを作られても困る(意味ない)ので、abstractにしておく。
〇コンストラクタ
/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="executeAction">実行アクション(必須)</param>
/// <param name="canExcuteAction">実行可否判定アクション</param>
/// <param name="dispatcher">ディスパッチャー</param>
public CommandExBase(Action<object> executeAction,
Func<object, bool> canExcuteAction = null,
Dispatcher dispatcher = null) {
this.ExecuteAction = executeAction;
this.CanExecuteAction = canExcuteAction;
this.Dispatcher = dispatcher ?? System.Windows.Application.Current.Dispatcher;
return;
}
コンストラクタで必須なのは、実行用アクション(executeAction)のみ。executeActionにnullが設定されたら、ArgumentNullExceptionをスローしても良いくらい。
〇要となるプロパティ
以下3つは、コマンドクラスの要であり、コンストラクタ引数を保持する。
/// <summary>実行用アクション</summary>
protected Action<object> ExecuteAction {get; private set;}

/// <summary>実行可否判定用アクション</summary>
protected Func<object, bool> CanExecuteAction {get; private set;}

/// <summary>ディスパッチャー</summary>
protected Dispatcher Dispatcher {get; set;}

Action系のプロパティは、Command内で実行する処理の要。Setterのアクセスを制限して、処理途中で切り替えさせない。
Actionって、イベントみたいに+=でメソッドを追加できるし。Setterをpublicにすると、いろいろ面倒になりそうだったので。
続きを読む
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0

コマンドクラスのリメイク(弐)

・スレッドセーフにアクセスするためのクラス
 非同期型コマンドを実装する以上、複数スレッドからのデータアクセスを考慮する必要がある。C#には、初期から排他制御するためのlockがあるので、それを使って実装する。
namespace Tawamuredays.Data {

/// <summary>
/// スレッドセーフなデータを保持する為のデータクラス
/// </summary>
public sealed class ConcurrentData<TData> {

#region コンストラクタ

/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="data">対象データ</param>
public ConcurrentData(TData data) {
this.value_ = data;
return;
}

#endregion

#region プロパティ

/// <summary>対象データ</summary>
private TData value_;

/// <summary>
/// 対象データを取得|設定します。
/// </summary>
public TData Value {
get {
lock (this.lockObj_) {
return this.value_;
}
}
set {
lock (this.lockObj_) {
this.value_ = value;
}
}
}

#endregion

#region private メンバー

/// <summary>ロック用オブジェクト</summary>
private readonly object lockObj_ = new object();

#endregion
}
}
スレッドセーフなコレクションなら、C#に標準装備されているので、それを使うのもありかな。
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0

コマンドクラスのリメイク(壱)

WPFかつMVVMパターンでアプリを実装しようと思えば、何はともあれほしいのが、コマンドクラスだ。
これがないとつまずくのに、標準で提供されないという(ストアアプリのテンプレートにはあるようだ)。
昔、そんな感じで書いてたな。

MVVMに必須なCommandクラスを作る。
多重実行対策用コマンドを作る。

コマンドクラスには、同期的に処理するタイプと、非同期的に処理するタイプが必要になる。連続で実行されても問題ないときは前者、実行されたくないときは後者が必要になる。
仕事で使っている非同期型コマンドクラスは、BackgroundWorkerを使って実装している。特に不都合はないのだが、仕事では使えないC#5.0以降で作りたくなった。
以下、実装したクラス
・ICommandを拡張したインターフェース
・スレッドセーフにアクセスするためのクラス
・汎用抽象クラス
・同期型コマンドクラス
・Awaitableなクラス
・非同期型コマンドクラス
続きを読む
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0

ポップアップは動かない(弐)

前回の続き。
親(ウィンドウ)についてこず、動かない子(ポップアップ)。
対策を調べる先は、当然StackOverflowである。
How can I move a WPF Popup when its anchor element moves?
ほほお、なるほど。という感じで、添付プロパティとして実装した。
用意する添付プロパティは、合計で三つ。

AnchorToParentWindow:Popupに添付するためのプロパティ。
FollowerPopups:フォロー中のポップアップリスト。内部用。
NowFollowing:フォロー中のWindowかどうか。内部用。

添付プロパティは、別にpublicである必要はなく、内部用としても活用できるので便利。続きを読む
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0

サイドバー背後固定表示サンプル

当ブログに書かれたソースコードは流用自由です。

バグ、スペルミス等はありうる事です。

ご利用の際は自己責任でお願いしますm(_ _)m