Calender

S M T W T F S
   1234
567891011
12131415161718
19202122232425
262728293031 
<< August 2018 >>

Categories

Archives

Recent Entries

Recent Comment

Recent Trackback

w closet×JUGEM

-

GitHub - dev4sys/PsTreeFolderBrowser: A TreeView in PowerShell

@media print { body { margin: 2mm 9mm; } .original-url { display: none; } #article .float.left { float: left !important; } #article .float.right { float: right !important; } #article .float { margin-top: 0 !important; margin-bottom: 0 !important; } } GitHub - dev4sys/PsTreeFolderBrowser: A TreeView in PowerShell

dev4sys/PsTreeFolderBrowser

README.md



iPadから送信
  • 2018.08.09 Thursday
  • 19:16

-

新しい競馬必勝法を着想

通勤の時、新しい競馬必勝法の&#127943;着想を得た。
みっつの必勝法で当て残しナシ!

iPadから送信
  • 2018.08.09 Thursday
  • 08:44

-

4級 | 自然環境研究センター

@media print { body { margin: 2mm 9mm; } .original-url { display: none; } #article .float.left { float: left !important; } #article .float.right { float: right !important; } #article .float { margin-top: 0 !important; margin-bottom: 0 !important; } } 4級 | 自然環境研究センター

4級

学校検定については、こちら(学校検定)をご覧ください。

3級、4級の第1回・第2回試験に合格された方に、「生物分類技能検定オリジナル野帳」をプレゼントします。
3級、4級第1回・第2回試験合格者プレゼントについて


受験資格・受験対象者

  • 受験資格:なし
  • 受験対象者:生物一般に興味がある方

出題形式・出題範囲

  • 出題形式:択一問題(マークシート)と、実物標本などを用いたスケッチ。
  • 出題範囲:広く生物一般を対象とした問題が出題されます。
    身近な生物(野生動植物種、栽培種、家畜、野菜、果物など)の区別や形に関する基礎的問題、スケッチなどが出題されます。

合格基準点

100点満点で60点

受験の流れ

受験申込上の注意事項や受験の手引きをご確認のうえお申し込みください。
受験申込上の注意事項  受験の手引き(1〜4級共通)(PDF:2.7MB)


インターネットによる申込

受付期間:7月1日(日)〜9月14日(金)

  1. 申込の流れ

    申込の流れ

  2. 受験申込登録

    受験申込入力フォームに申込情報や支払先等を入力してください。
    「仮登録完了」画面には払い込み時に必要な情報がございますので、必ずプリントアウトするか、メモをお取りください。
    ※受験申込入力はPCをご利用ください。携帯電話からのお申し込みは出来ません。
    ※「仮登録完了」画面と同様の内容がご入力いただいたEメールアドレス(携帯電話メールアドレス不可)に自動送信されますが、遅延やメールアドレスの間違いなどで届かない場合がございます。

  3. 受験手数料の払い込み
    • 受験手数料:3,080円
    • コンビニペーパーレス決済(支払手数料無料)です。以下のコンビニエンスストアから支払先を選び、受験手数料をお支払いください。
      • セブンイレブン、ローソン、ファミリーマート、サークルKサンクス、ミニストップ、デイリーヤマザキ、ヤマザキデイリーストア、セイコーマート
    • 受験手数料のお支払いをもって、「受験申込」が完了します。「受験申込の完了」の連絡は、「受験票」の送付をもってかえさせていただきます。
  4. 受験票の受取
    • 試験日2週間前に発送します。
    • 受け取ったらすぐに開封し、受験級、試験会場、時間、持ち物、裏面の注意事項等を確認してください。
    • 試験日の1週間前の時点で届いていない場合は、検定事務局にお問い合わせください。
  5. 試験の実施
    • 受験票を忘れた場合は、受験できないことがあります。
    • 試験会場に関するお問い合わせは、検定事務局へお願いいたします。
  6. 結果通知の受取
    • 試験結果(合否および得点)は検定委員会による審査の後、郵送にて直接ご本人宛に通知いたします。
      合格者へは認定証が同封されます。認定証見本(PDF:96KB)
      ※結果通知発送後、ホームページに合格者の受験番号と正解・配点を約1ヶ月間掲載します。

インターネットによる申込に進む方はこちら

4級インターネット受験申込入口(申込受付は7月1日からです)



郵送による申込

受付期間:7月1日(日)〜9月14日(金)当日消印有効

  1. 受験申込書の入手
  2. 受験申込書の記入
    • 記入例を確認のうえ、申込書に必要事項をもれなく記入し、押印してください。
  3. 受験手数料の払い込み
    • 受験手数料:3,080円
    • 郵便局にて、備え付けの青色払込用紙を使用し、受験手数料をお支払いください。 払込手数料は申込者のご負担となりますので、あらかじめご了承ください。

    手数料の払込先

  4. 必要書類の送付
    • 郵便事故防止のため、郵便局の窓口で簡易書留としてお出しください。
  5. 受験票の受取
    • 試験日2週間前に発送します。
    • 受け取ったらすぐに開封し、受験級、試験会場、時間、持ち物、裏面の注意事項等を確認してください。
    • 試験日の1週間前の時点で届いていない場合は、検定事務局にお問い合わせください。
  6. 試験の実施
    • 受験票を忘れた場合は、受験できないことがあります。
    • 試験会場に関するお問い合わせは、検定事務局へお願いいたします。
  7. 結果通知の受取
    • 試験結果(合否および得点)は検定委員会による審査の後、郵送にて直接ご本人宛に通知いたします。
      合格者へは認定証が同封されます。認定証見本(PDF:96KB)
      ※結果通知発送後、ホームページに合格者の受験番号と正解・配点を約1ヶ月間掲載します。

日程(受付期間、試験日時、開催地・会場、結果通知等)

平成30年度

受付期間 インターネット:7月1日(日)〜9月14日(金)
郵送:7月1日(日)〜9月14日(金)当日消印有効
*郵送取り寄せは、申込受付終了日の1週間前までです
申込書ダウンロード期間 7月1日(日)〜9月13日(木)
受験票の発送 10月26日(金)
試験日 11月11日(日)
試験時間 10:00〜12:00(120分間)
試験会場 札幌:酪農学園大学
東京:青山学院大学青山キャンパス
大阪:大和大学
福岡:福岡県中小企業振興センター
結果通知 平成31年1月31日(木)

お問い合わせ

一般財団法人自然環境研究センター 生物分類技能検定事務局
〒130-8606 東京都墨田区江東橋3丁目3番7号
TEL:03-6659-6110(平日9時30分〜17時30分)  FAX:03-6659-6320(24時間受付)
※ 検定事務局への直接のお越しはご遠慮ください。



iPadから送信
  • 2018.08.09 Thursday
  • 08:43

-

【C#】ReactiveProperty全然分からねぇ!って人向けのFAQ集【修正済】

@media print { body { margin: 2mm 9mm; } .original-url { display: none; } #article .float.left { float: left !important; } #article .float.right { float: right !important; } #article .float { margin-top: 0 !important; margin-bottom: 0 !important; } } 【C#】ReactiveProperty全然分からねぇ!って人向けのFAQ集【修正済】

【C#】ReactiveProperty全然分からねぇ!って人向けのFAQ集【修正済】

概要

 C#でMVVMパターンを組んで開発しようとした際に役に立つライブラリの一つにReactivePropertyがあります。
 ただ、これを使って書くと、従来とは記述が大きく変わってしまいますので、それなりに慣れが必要となります。
 以下、そんなReactivePropertyの使い方についてのFAQ集となります(自分が躓いたところばかりなので実質備忘録)。

※2017/12/31追記:ReactivePropertyのメンテナーの一人でいらっしゃるかずき(Kazuki Ota)さんから指摘を賜り、記事を大幅に修正しました。

FAQ集

Q. 具体的にはどう便利なの?

  • INotifyPropertyChangedインターフェースを実装したり、そうした通知機能がコミコミのクラスを継承したりする必要がない。要するに 記述量が少なくて済む
  • 「値が変更された時にアクションを起こす」「ボタンを押すなどの操作をした時にアクションを起こす」ことを、Subscribeメソッドで購読することにより表現できる。要するに setアクセサーにごちゃごちゃ書かなくていい
  • 入力した値のチェック機能 がある。つまり、「入力内容が全て正常な場合のみ、入力ボタンを有効にする」などといった処理を楽に書くことができる
/* --------------- */
/* |従来の記述方法| */
/* --------------- */
using System.ComponentModel;
class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(string parameter)
     => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(parameter));
}
class ViewModel : ViewModelBase 
{
    private int selectedMode;
    public int SelectedMode {
        get{ return selectedMode; }
        set{
            if(value == selectedMode)
                return;
            selectedMode = value;
            DoFunc(selectedMode);
            NotifyPropertyChanged(nameof(SelectedMode));
        }
    }
}

/* --------------------------------- */
/* |ReactivePropertyにおける記述方法| */
/* --------------------------------- */
using System;
using System.ComponentModel;
using Reactive.Bindings;
class ViewModel : INotifyPropertyChanged {
    public event PropertyChangedEventHandler PropertyChanged;
    public ReactiveProperty<int> SelectedMode {get;} = new ReactiveProperty<int>();

    // コンストラクタ内で
    SelectedMode.Subscribe(x => DoFunc(x));
}

Q. あれ、ReactivePropertyだとINotifyPropertyChanged要らないんじゃなかったっけ?

 確かに書かなくてもプログラムは動きます。ただ、Visual C#の仕様上、上記のように継承していないと メモリーリークの可能性があります。……アイエエエ!?ナンデ!?メモリーリークナンデ!?

 参考にすべき資料:
  【WPF】ViewModelがINotifyPropertyChangedを実装していないとメモリリークする件 - aridai.NET
  MVVMでメモリリークしちゃってました 原因と対策編 - かずきのBlog@hatena

 また、メモリーリーク絡みで言いますと、ReactivePropertyReactiveCommandなどはIDisposableを継承していますので、使用後はDisposeする必要があります。単独で自己完結しているような型ならGC任せでも良いのですが、後述の質問「Q. 既存のModel・ViewModelを全部書き換えるの辛くない?」のように他のオブジェクトがイベントによって紐付けられている場合、Disposeしておくことが望ましいでしょう。具体的にはこんな感じ。

class ViewModel : INotifyPropertyChanged, IDisposable {
    public event PropertyChangedEventHandler PropertyChanged;
    // Disposeが必要なReactivePropertyやReactiveCommandを集約させるための仕掛け
    private CompositeDisposable Disposable { get; } = new CompositeDisposable();
    // ReactivePropertyやReactiveCommandを用意する
    public ReactiveProperty<int> Hoge{ get; }
    public ReactiveCommand Fuga{ get; };
    public ViewModel(){
        // AddToメソッドでDisposeしたいオブジェクトをDisposableプロパティ(の実体)に登録する
        this.Hoge = new ReactiveProperty<int>().AddTo(this.Disposable);
        this.Fuga = new ReactiveCommand ().AddTo(this.Disposable);
    }
    public void Dispose(){
        // まとめてDisposeする
        Disposable.Dispose();
    }
}

 参考資料:
  ReactivePropertyの後始末 - かずきのBlog@hatena

Q. ReactiveProperty<T>はどう記述すればいいの?

 ReactiveProperty<T>型はT型の変数を入れる箱のようなもの。
 通知機能を内包しているのでそのままXAMLにBindingできるし、値の変更を反映させるのも簡単。
 なお、ReactiveProperty<T>型からT型の値を取り出す際は、Valueプロパティを参照する(C#側でもXAML側でも同様)。

C#側の記述.cs

class ViewModel : INotifyPropertyChanged{
    // プロパティ
    // 宣言と同時に初期化 or コンストラクタで初期化する場合は「private set;」の記述不要
    public ReactiveProperty<int> SelectedMode { get; private set; }

    // メソッド内での記述
    //デフォルト値で初期化
    SelectedMode = new ReactiveProperty<int>();
    //指定した数値(この場合は3)で初期化
    SelectedMode = new ReactiveProperty<int>(3);
    // 値を引き出す・書き換える際はValueプロパティを参照すること
    int selectedMode = SelectedMode.Value;
    SelectedMode.Value = 2;
}

XAML側の記述.xml

<Combobox SelectedIndex = {Binding SelectedMode.Value, Mode=TwoWay}>

Q. ReactiveProperty<T>の値が変更した時の動作はどう記述すればいいの?

 Subscribeメソッドを使う。これの引数にIObserver<T>を渡すことで購読できるので、「値が変更した際にはこういったアクションを起こす」といったことをシンプルに記述できる。
 なお、以下の例ではラムダ式を渡しているが、using System;しないとラムダ式をIObserver<T>に変換できないので注意!

using System;
//値が変更された時の動作
SelectedMode.Subscribe(_ => DoFunc(SelectedMode.Value));
//値が変更された時の動作(色々行うので{}が必要)
SelectedMode.Subscribe(_ => {
    DoFunc1(SelectedMode.Value);
    DoFunc2(SelectedMode.Value);
    DoFunc3(SelectedMode.Value);
});

Q. ReadOnlyReactivePropertyって何?

 まず、「ReactiveProperty<T>は他のReactiveProperty<T>から作成できる」ことを説明しておきましょう。例えば「あるTextBoxの中身を書き換えると、それを加工した結果がTextBlockに表示される」ような動きが可能になります。要するに連動ですね。

using System.Reactive.Linq;
// 変数を宣言
public ReactiveProperty<int> Input1 { get; } = ReactiveProperty<int>();
public ReactiveProperty<int> Input2 { get; } = ReactiveProperty<int>();
public ReactiveProperty<int> Output1 { get; }
public ReactiveProperty<bool> Output2 { get; }
public ReactiveProperty<string> Output3 { get; }

// 定義する際に、どう加工するかをメソッドチェーンで示す
// (Output1は、Input1を2倍にした数値となる)
Output1 = Input1.Select(x => x * 2).ToReactiveProperty();
// この「Select」は、普通のLINQと同様、型変換にも使える
// (Output2は、Input1が偶数ならtrue、機数ならfalseとなる)
Output2 = Input1.Select(x => (x % 2 == 0)).ToReactiveProperty();
// 2つ以上のReactivePropertyを合成することも可能
// (Output3は、Input1 == Input2なら"同じ", それ以外なら"違う"となる)
Output3 = Input1.CombineLatest(Input2, (x, y) => (x == y ? "同じ" : "違う")).ToReactiveProperty();

 そして上記のように連動している場合、「連動先は連動元で決まるから、連動先は読み取り専用でも構わない」ということがよくあります。そういった際に用いるのがReadOnlyReactivePropertyです。
 ……ReadOnlyReactivePropertyの使い方は、ReactivePropertyだった箇所を単純に置き換えるだけですので省略します(上記で言えばOutput1Output3に用いる)。

 なお、CombineLatestメソッドは、3つ以上のReactivePropertyを合成するのにも使えます。

using System.Reactive.Linq;
public ReactiveProperty<int> Input1 { get; }
public ReactiveProperty<string> Input2 { get; }
public ReactiveProperty<bool> Input3 { get; }
public ReactiveProperty<decimal> Input4 { get; }
public ReactiveProperty<string> Output1 { get; }
public ReactiveProperty<string> Output2 { get; }

Output1 = Input1.CombineLatest(Input2, Input3,
    (x, y, z) => func1(x, y, z)
).ToReactiveProperty();

Output2 = Input1.CombineLatest(Input2, Input3, Input4,
    (x, y, z, w) => func2(x, y, z, w)
).ToReactiveProperty();

Q. ラムダ式の「() => hoge();」と「_ => hoge();」って何が違うの?

 前者は「引数を受け取らず、hoge()の返り値を返す」、後者は「引数を1つ取り、hoge()の返り値を返す」といった意味です。実は 変数名として「_」1文字だけでも全然アリ なのでその値を使えるのですが、「_」1文字にすることで「引数は取るけど使わないよ」といった意思表示をすることができます。

 実はReactivePropertyの場合、Subcribeメソッド内でラムダ式を使うと、引数で呼び出し元の変数の中身を使用することができます。例えば、ReactiveProperty<Type> Xに対してX.Subcribe(x => hoge(x));といったコードが書けます(この際、ラムダ式内の変数xはType型となる)。もっとも、ReactiveCommand型だとobject型が引数の型にやってきますが……。

using System;
// 値が変更された時の動作
SelectedMode.Subscribe(_ => DoFunc(SelectedMode.Value));
// 実はこういった風に書ける
SelectedMode.Subscribe(x => DoFunc(x));
// 更に、DoFuncメソッドが引数1のみでオーバーロードが無ければここまで略せる(意味は上と等価)
SelectedMode.Subscribe(DoFunc);

 しかし、ReactiveProperty<Type> X購読するイベント内でXの中身を使用しない 場合、X.Subcribe(_ => hoge());といった風に 「_」を引数名として使用することで明示する ことができるのです。

Q. さっきから言ってる「購読」ってどういう意味なの?

「購読」を説明する前に、まず「イベント」について説明しましょう。
 イベントとは、「作業を完了した」「ボタンを押した」など、「別の行動を起こすためのキッカケとなる行動」のことです。
 ここで、「別の行動」を起こすオブジェクト(イベント発生側)と「キッカケとなる行動」を起こすオブジェクト(イベント受取側)は 基本的に別である ことに注意しましょう。
 イベントに関係する処理としては、大きく分けて次の3種類があります。

  • 処理1:イベント発生側に、イベント受取側の情報を登録する
  • 処理2:イベント発生側が、「イベントを起こした」という情報をイベント受取側に送信する
  • 処理3:イベント発生側から、イベント受取側の情報を削除する

observableobserver.png
(画像引用元:++C++; // 未確認飛行 C)

 そして「購読」とは、この処理1のことを指します。つまり、ReactiveProperty<T>Subcribeメソッドでラムダ式を受け取る(=購読する)場合、ReactiveProperty<T>が「(値を変更する)イベント発生側」、ラムダ式が「イベント受取側」となります。
 また、後述するReactiveCommandにもSubcribeメソッドがありますが、こちらもReactiveCommandが「(ボタン操作などの)イベント発生側」となります。

Q. ReactiveCommandはどう記述すればいいの?

 先にICommandについて説明すると、これはボタン操作などの「コマンド」をMVVM用に抽象化したものです。コマンドには「実行できるか」という要素(CanExecuteメソッド)と「実行時に何をするか」という要素(Executeメソッド)があり、それぞれを実装する必要があります。
 一方、ReactiveCommand型を使うと、そうした実装の手間を大幅に省くことができます。こちらはReactiveProperty<T>型と異なり、.Valueを付けなくてもいいことに注意しましょう。

C#側の記述.cs

/* --------------- */
/* |従来の記述方法| */
/* --------------- */
using System;
using System.Windows.Input;
public class CommandBase : ICommand
{
    Action action;
    public bool CanExecute(object parameter) => true;
    public event EventHandler CanExecuteChanged;
    public void Execute(object parameter) { action(); }
    public CommandBase(Action action) { this.action = action; }
}
class ViewModel : INotifyPropertyChanged
{
    public ICommand ButtonCommand{ get; private set; }
    private void ButtonAction(){(中略)}
    public ViewModel(){
        ButtonCommand = new CommandBase(ButtonAction);
    }
}

/* --------------------------------- */
/* |ReactivePropertyにおける記述方法| */
/* --------------------------------- */
using Reactive.Bindings;
using System;
class ViewModel : INotifyPropertyChanged{
    public ReactiveCommand ButtonCommand {get;} = new ReactiveCommand();
    private void ButtonAction(){(中略)}
    public MainViewModel(){
        ButtonCommand.Subscribe(_ => ButtonAction());
    }
}

XAML側の記述.xml

<Button Command = {Binding ButtonCommand}>

Q. ReactiveCommandもSubscribeでイベントを購読するんだよね?

 その通りです。ReactiveProperty<T>では「値が変更された時に発動」していましたが、ReactiveCommandでは「コマンドが実行された時に発動」します。

Q. 「次の条件を満たした場合にコマンドを有効にする」処理って書くの面倒なんだよねー

 そういった時にこそReactivePropertyです。ReactivePropertyにはToReactiveCommandという拡張メソッドがあり、これを使うとIObservable<bool>からReactiveCommand型を生成できます。これから、
IObservable<bool>がtrueになった(=条件を満たした)ときにだけReactiveCommand先のオブジェクトが有効になる」
といった処理を簡単に記述できるようになります。
 また、複数の条件を組み合わせることで、「全ての条件を満たした時」や「どれか1つの条件を満たした時」といった有効条件も記述可能です。

using System;
using Reactive.Bindings;
using System.Reactive.Linq;

// 何らかのコマンド
public ReactiveCommand ButtonCommand {get; private set; }
// 何らかのフラグ
public ReactiveProperty<bool> ButtonFlg1 { get; } = new ReactiveProperty<bool>();
public ReactiveProperty<bool> ButtonFlg2 { get; } = new ReactiveProperty<bool>();
public ReactiveProperty<bool> ButtonFlg3 { get; } = new ReactiveProperty<bool>();

// フラグが有効な時にのみコマンドを有効にする(例えばボタンのコマンドが無効になっている際は、ボタン自体も無効色になる)
ButtonCommand = ButtonFlg1.ToReactiveCommand();
// フラグが2つとも有効な場合にのみコマンドを有効にする
ButtonCommand = ButtonFlg1.CombineLatest(ButtonFlg2, (x,y) => x & y).ToReactiveCommand();
// フラグが3つとも有効な場合にのみコマンドを有効にする
ButtonCommand = new[] { ButtonFlg1, ButtonFlg2, ButtonFlg3 }
    .CombineLatest(x => x.All(y => y)).ToReactiveCommand();

// フラグが1つでも有効な場合にのみコマンドを有効にする
ButtonCommand = ButtonFlg1.CombineLatest(ButtonFlg2, (x,y) => x | y).ToReactiveCommand();
// フラグが1つでも有効な場合にのみコマンドを有効にする
ButtonCommand = new[] { ButtonFlg1, ButtonFlg2, ButtonFlg3 }
    .CombineLatest(x => x.Any(y => y)).ToReactiveCommand();

// フラグが全て有効な場合にのみコマンドを有効にする
ButtonCommand = new[] { ButtonFlg1, ButtonFlg2, ButtonFlg3 }
    .CombineLatestValuesAreAllTrue().ToReactiveCommand();
// フラグが全て無効な場合にのみコマンドを有効にする
ButtonCommand = new[] { ButtonFlg1, ButtonFlg2, ButtonFlg3 }
    .CombineLatestValuesAreAllFalse().ToReactiveCommand();

Q. 入力値チェックってどう書けばいいの?

  • ValidationAttributeを継承したクラスをReactiveProperty<T>にあてがう。「IsValidメソッドがtrueを返す=入力値が正常」ということなので注意
  • 以下のケースでは「入力した文字列がint型にパースできるか」をValidation内容としているが、これは入力が文字列だからこそできるのであって、例えばReactiveProperty<int>に対してはその手が使えない(パース可否でValidationできない)ことに注意
// バリデーション用のクラス
// (以下のサンプルは、int型にパースできた時のみ「入力値が正常」だと判断する)
using System.ComponentModel.DataAnnotations;
public class IntValidationAttribute : ValidationAttribute {
    public override bool IsValid(object value)
        => int

 
  • 2018.08.08 Wednesday
  • 16:55

-

ViewのコードビハインドからViewModelの型や実装をを気にせずメソッド&プロパティにアクセスする

@media print { body { margin: 2mm 9mm; } .original-url { display: none; } #article .float.left { float: left !important; } #article .float.right { float: right !important; } #article .float { margin-top: 0 !important; margin-bottom: 0 !important; } } ViewのコードビハインドからViewModelの型や実装をを気にせずメソッド&プロパティにアクセスする

ViewのコードビハインドからViewModelの型や実装をを気にせずメソッド&プロパティにアクセスする

例えば……

WPFで画面にドラッグ&ドロップでファイルを投げた時の処理を例として。
ViewのXAMLで

View.xaml

<Window x:Class="AmazonToYamatoB2Converter.Views.View"
        AllowDrop="True"
        Drop="View_Drop">

    <Window.DataContext>
        <vm:ViewModel/>
    </Window.DataContext>

    <Grid>
        <!-- 画面 -->
    </Grid>
</Window>

ってして、コードビハインドでドラッグ&ドロップを処理しようとするんだけど

View.xaml.cs

    public partial class View : Window
    {
        public View()
        {
            InitializeComponent();
        }

        private void View_Drop(object sender, DragEventArgs e)
        {
            var dropFileList = (e.Data.GetData(DataFormats.FileDrop) as string[]).ToList();
            // ここから先はViewModelの処理としたい
        }

    }

ドラッグ&ドロップで渡されたファイル(パス)の処理はViewModelの責務じゃないかなと思うんですよ。
Modelに渡したりとかするわけですし。
ViewModelクラスにはその為の処理としてpublic void AddDragAndDropsFiles(List<string> fileList)ってメソッドが実装されているとします。
で、そのメソッド呼ぶ為にViewからViewModelを参照するわけです。

普通にViewクラスからViewModelクラスを参照する

View.xaml.cs

        private ViewModel VM
        {
            get { return this.DataContext as ViewModel; }
        }

        private void View_Drop(object sender, DragEventArgs e)
        {
            var dropFileList = (e.Data.GetData(DataFormats.FileDrop) as string[]).ToList();
            // ここから先はViewModelの処理としたい
            this.VM. AddDragAndDropsFiles(dropFileList);
        }

まぁよくあるやつです。
これの面倒な点は、ViewModelって型を書かないと行けないって所です。
名前空間usingして、ViewModelの型を補完使って入力。(逆もある)
ViewModelの型を変更しくなったらコードビハインドも変更しないといけない。

ならInterfaceは?

書くの面倒だからコード例は出さない。
確かにそれでいいかもしれない。
でも、それも結局Interfaceの型を変更する場合同じ事なんですよね。
usingするのも変わらんし。
Iなんたらかんたらってのを沢山継承するViewModelになることないですか?

Behavior作れば?

書くの(ry
この辺りを参照して下さい。
確かにコードビハインドにコード書く必要もなくなるのいいかもね。
Interface書くのすら面倒臭がる俺にこんな長いコードを書けとか鬼か。
再利用性はあるかもしれない。
が、でもちょっと使いづらとかで機能追加してコードが読みづらくなるの、よくある話ですよね。
そもそもドラッグ&ドロップでのファイルの受け渡し程度にこんな量のコード書くの?

これでいいんじゃね?

C# 4.0からだけど、dynamicってキーワードがある。
これを使うと

View.xaml.cs

        private dynamic VM
        {
            get { return this.DataContext; }
        }

        private void View_Drop(object sender, DragEventArgs e)
        {
            var dropFileList = (e.Data.GetData(DataFormats.FileDrop) as string[]).ToList();
            // ここから先はViewModelの処理としたい
            this.VM.AddDragAndDropsFiles(dropFileList);
        }

こうなる。
何が良いって、VMはViewModelクラスじゃなくてもpublic void AddDragAndDropsFiles(List<string> fileList)メソッドを実装しているクラスならOKって所。
ViewがViewModelの型や実装を気にしなくて良い。
ViewModelの事を気にせずViewだけの実装を書いておいて、後ViewModel実装するって事も出来る。
なお、呼び出してるメソッドが実装されてなかったらコンパイルエラーは発生せず、実行時にRuntimeBinderExceptionという例外が発生します。

「C#という言語で、メソッド実装してなかったらコンパイルエラーじゃなくて実行時エラーになるのってどうなの?」
という指摘は最もだと思います。潔癖症には辛いかもしれない。
でも、InterfaceやBehaviorの作成よりは読みやすいし、書くコード量も少なくて済むので悪くないんじゃ無いかと思います。



iPadから送信
  • 2018.08.08 Wednesday
  • 16:55

-

ReactivePropertyが便利すぎてとても助かる [C#][WPF] - nprogram’s blog

@media print { body { margin: 2mm 9mm; } .original-url { display: none; } #article .float.left { float: left !important; } #article .float.right { float: right !important; } #article .float { margin-top: 0 !important; margin-bottom: 0 !important; } } ReactivePropertyが便利すぎてとても助かる [C#][WPF] - nprogram’s blog

ReactivePropertyが便利すぎてとても助かる [C#][WPF]

C#

ReactivePropertyの使い方を学習していきます

画面

f:id:nprogram:20180210194943p:plain

コード

[MainWindowViewModel.cs]

using Reactive.Bindings;
using System;
using System.Linq;
using System.Reactive.Linq;

namespace ReactivePropertySample
{
    class MainWindowViewModel
    {
        public ReactiveProperty<string> Input { get; private set; }
        public ReactiveProperty<string> Output { get; private set; }
        public ReactiveCommand ClearCommand { get; private set; }
        public ReactiveCommand SetCommand { get; private set; }

        public MainWindowViewModel()
        {
            // ViewModelクラスのコンストラクタでReactiveProperty間の関連を定義

            // ReactivePropertyを作成する基本的な方法は、以下の2つ
            // 1. new演算子を使って生成する
            //    コンストラクタの引数にデフォルト値を指定する。指定しない場合は、その型のでデフォルト値が使われる)
            // 2. IObservable<T> に対してToReactiveProperty拡張メソッドを呼ぶ
            this.Input = new ReactiveProperty<string>(""); // デフォルト値を指定してReactivePropertyを作成
            this.Output = this.Input
                .Delay(TimeSpan.FromSeconds(1)) // 1秒間待機して
                .Select(x => x.ToUpper()) // 大文字に変換して
                .ToReactiveProperty(); // ReactiveProperty化する


            // CommandのExecuteが呼ばれたときの処理はSubscribeメソッドで指定します。
            // 先ほど作成したViewModelのInputプロパティが空じゃないときに、Inputプロパティを空にするCommandを追加したコードは以下のようになります。
            this.ClearCommand = this.Input
                .Select(x => !string.IsNullOrWhiteSpace(x)) // Input.Valueが空じゃないとき
                .ToReactiveCommand(); // 実行可能なCommandを作る

            // Commandの動作を定義する
            this.ClearCommand.Subscribe(_ => this.Input.Value = "");


            // 現在の日付を取得する
            DateTime dtToday = DateTime.Today;

            // 実行可能なCommandを生成する
            this.SetCommand = new ReactiveCommand();

            // Commandの動作を定義する
            this.SetCommand.Subscribe(_ => this.Input.Value += dtToday.ToString());
        }
    }
}

[MainWindow.xaml]

<Window x:Class="ReactivePropertySample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ReactivePropertySample"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>
    
    <StackPanel>
        <Label Content="入力" />
        <TextBox Text="{Binding Input.Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        <Label Content="出力" />
        <TextBlock Text="{Binding Output.Value}"/>
        <Button Content="SET Today Date" Command="{Binding SetCommand}" />
        <Button Content="CLEAR Text" Command="{Binding ClearCommand}" />
    </StackPanel>
</Window>

他のファイルは変更ありません。

ReactivePropertyの勉強は以下のサイトがおすすめです。

  • MVVMとリアクティブプログラミングを支援するライブラリ「ReactiveProperty v2.0」オーバービュー blog.okazuki.jp

  • MVVMをリアクティブプログラミングで快適にReactivePropertyオーバービュー blog.okazuki.jp

tmori3y2.hatenablog.com

qiita.com



iPadから送信
  • 2018.08.08 Wednesday
  • 16:55

-

コードビハインドからViewModelのメソッドを呼び出す - がりらぼWP7 ~WindowsPhoneプログラミング情報発信ラボ~

@media print { body { margin: 2mm 9mm; } .original-url { display: none; } #article .float.left { float: left !important; } #article .float.right { float: right !important; } #article .float { margin-top: 0 !important; margin-bottom: 0 !important; } } コードビハインドからViewModelのメソッドを呼び出す - がりらぼWP7 ~WindowsPhoneプログラミング情報発信ラボ~

コードビハインドからViewModelのメソッドを呼び出す

C#


MVVM(っぽいもの)で設計しているとViewとバインドしてるコマンドだけではViewModelを呼び出すのがつらくなり、たとえばView依存するOpanFileDialogなどはコードビハインドに書くべきです。そういう時に、コードビハインドからViewModelのメソッドを呼び出せたら便利です。
ViewModelはコードビハインドのDataContextに格納されていて、これをキャストするだけで簡単にViewModelが呼び出せちゃいます。

var viewModel = DataContext as ViewModel;

まあコードからバインドでコマンド実行できる方法を知ってればいいんですけどね。僕知らないですし。
そもそもぼくのMVVMの知識が間違ってる気しかしないので。

Permalink | コメント(0) | トラックバック(0) | 23:06



iPadから送信
  • 2018.08.08 Wednesday
  • 16:55

-

MVVMパターンのシンプルなサンプル(Prism + ReactiveProperty) 言語: C#, XAML Visual Studio 2013 用

https://code.msdn.microsoft.com/windowsdesktop/MVVMPrism-ReactiveProperty-dc36af04


iPadから送信
  • 2018.08.08 Wednesday
  • 16:55

-

Get TreeViewItem for TreeView logical element

https://social.msdn.microsoft.com/Forums/vstudio/en-US/81b3bf3f-5767-4907-8d76-92a78c8b987c/get-treeviewitem-for-treeview-logical-element?forum=wpf


iPadから送信
  • 2018.08.08 Wednesday
  • 11:24

-

Control.PreviewMouseDoubleClick イベント (System.Windows.Controls)

https://msdn.microsoft.com/ja-jp/library/system.windows.controls.control.previewmousedoubleclick(v=vs.110).aspx


iPadから送信
  • 2018.08.07 Tuesday
  • 15:42