漫坊亭

社会の底辺プログラマ

(自分用翻訳) Caliburn.Micro > Documentation > All About Actions

原文へのリンク (google翻訳)

All About Actions

私たちは簡単にPt.1にアクションを導入したが、そんなに多くを知ることがあります。私たちの調査を開始するために、我々は、単純な「Hello」の例を取ると、それは我々が明示的に行動ではなく、利用規則を作成するときにどのように見えるかを確認します。ここでは、XAMLは次のとおりです。

<UserControl x:Class="Caliburn.Micro.Hello.ShellView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
             xmlns:cal="http://www.caliburnproject.org">
    <StackPanel>
        <TextBox x:Name="Name" />
        <Button Content="Click Me">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <cal:ActionMessage MethodName="SayHello" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
    </StackPanel>
</UserControl> 

あなたが見ることができるように、アクションはそれのトリガ機構のためSystem.Windows.Interactivityを活用しています。これは、あなたがActionMessageの送信をトリガするSystem.Windows.Interactivity.TriggerBaseから継承何かを使用できることを意味します。おそらく最も一般的なトリガーはEventTriggerがあるが、あなたは想像トリガーのほとんどすべての種類を作成したり、すでにコミュニティで作成されたいくつかの一般的なトリガーを活用することができます。 ActionMessageは、もちろん、このマークアップのCaliburn.Micro固有の部分です。 これは、トリガが発生したとき、私たちはのメッセージ送信する必要があることを示している」SayHelloを。"だから、なぜ私は言語を使っています」というメッセージを送る」の代わりに、この機能を説明する際に「メソッドを実行しますか」?それが面白いと強力な部分です。 ActionMessageはそれを扱うことができ、ターゲット·インスタンスを検索するビジュアルツリーを介して気泡。ターゲットが検出されたが、「SayHello」メソッドを持っていない場合が見つかるまでは、「ハンドラ」が見つからない場合、フレームワークは例外をスロー、バブルしていきます。 ActionMessageこの発泡性質は興味深いシナリオ、マスタ/詳細はキーユースケースであることの数に便利です。注意すべきもう一つの重要な特徴はアクションガードです。ハンドラーが「_SayHello」のメッセージを発見された場合、それはそのクラスにもプロパティまたは「CanSayHello。"という名前のあなたはガード性を持っており、あなたのクラスはINotifyPropertyChangedのを実装している場合いずれかの方法があるかどうかをチェックすると、フレームワークは、観察しますそのプロパティとの変化に応じてガードを再評価します。我々は、以下にさらに詳細に方法ガードについて説明します。

Action Targets

今、あなたはおそらくActionMessageのターゲットを指定する方法を迷っています。上記のマークアップを見てみると、そのターゲットがどうなるかの目に見える兆候がありません。だから、ここでそれはから来たのでしょうか?我々はCaliburn.Micro(以下、CM)はビューを作成し、ViewModelBinderを使用してのViewModelにバインドされたモデル·ファーストアプローチを使用したので、それが私たちのためにこれを設定しました。 ViewModelBinderを通過するものは、その作用対象が自動的に設定されています。しかし、あなたは添付プロパティのAction.Targetを使用して、同様にそれを自分で設定することができます。このプロパティを設定すると、プロパティを宣言しているノードに接続されているビジュアルツリー内のActionMessage「handler」を配置します。あなたは多くの場合、これらの二つのことを同じようにしたいので、それはまた、同じ値にDataContextのを設定します。ただし、必要に応じたDataContextからAction.Targetを変化させることができます。代わりに単にAction.TargetWithoutContext添付プロパティを使用します。 Action.Target約良いところは、あなたが可能System.Stringに設定することができ、CMはそのキーとして指定された値を使用して、IoCコンテナからインスタンスを解決するために、その文字列を使用することです。これは、あなたがそう望むならばビュー·ファーストMVVMを行うための良い方法を提供します。あなたがAction.Targetセットをしたいとあなたはアクション·バインディング/表記法も同様に適用する場合は、同じようにBind.Model添付プロパティを使用することができます。

View First

public class MefBootstrapper : BootstrapperBase
{
    //same as before

    protected override void OnStartup(object sender, StartupEventArgs e)
    {
        Application.RootVisual = new ShellView();
    }

    //same as before
} 

我々はビュー·ファーストを使用しているため、我々は、非汎用ブートストラップから継承されてきました。 MEFの設定は、私は簡潔のためにそれを残しているので、以前に見たものと同じです。変更された唯一の他の事は、ビューが作成されます方法です。このシナリオでは、単純に、OnStartup上書きビューに自分自身をインスタンス化し、RootVisualとして設定(またはWPFの場合は表示を呼び出します)。我々が明示的に指定し、契約を追加することによって、私たちのShellViewModelをエクスポートする方法次に、我々はわずかに変えます:

[Export("Shell", typeof(IShell))]
public class ShellViewModel : PropertyChangedBase, IShell
{
    //same as before
}

最後に、我々はすべてのバインディングVMに引き出し、実行するために私たちのビューを変更します:

<UserControl x:Class="Caliburn.Micro.ViewFirst.ShellView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:cal="http://www.caliburnproject.org"
             cal:Bind.Model="Shell">
    <StackPanel>
        <TextBox x:Name="Name" />
        <Button x:Name="SayHello"
                Content="Click Me" />
    </StackPanel>
</UserControl> 

Bind.Model添付プロパティの使用を注意してください。これは、IoCコンテナからキーによって私たちのVMを解決Action.Targetを設定し、DataContextの、すべての規則が適用されます。私はそれが完全にCMでサポートされているかを見る·ファースト開発を示すためにいいだろうと思ったが、主に私はあなたがアクションのターゲットと各技術を使用しての意味を設定することができる明確な様々な方法をしたいです。ここで利用可能な添付プロパティの概要は次のとおりです。

Action.Target - Action.Targetプロパティと指定されたインスタンスへのDataContextプロパティの両方を設定します。文字列値は、IoCコンテナからインスタンスを解決するために使用されています。 Action.TargetWithoutContext - 指定されたインスタンスにのみAction.Targetプロパティを設定します。文字列値は、IoCコンテナからインスタンスを解決するために使用されています。 Bind.Model - ViewFirst - 指定されたインスタンスにAction.TargetとのDataContextプロパティを設定します。ビューに規則を適用します。文字列値は、IoCコンテナからインスタンスを解決するために使用されています。 (ウィンドウ/ユーザーコントロール/ページのようなルートノードで使用してください。) Bind.ModelWithoutContext - ビューファースト - 指定されたインスタンスへのAction.Targetはです設定します。ビューに規則を適用します。 (DataTemplateを内部に使用します。) View.Model - ViewModelに - 最初に - 指定されたVMインスタンスのビューを検索し、コンテンツサイトでそれを注入します。 VMはAction.TargetとのDataContextに設定します。ビューに規則を適用します。

Action Parameters

パラメータ:さて、ActionMessageの別の興味深い側面を見てみましょう。この動作を確認するには、のは、など当社独自のViewModelファーストブートストラップ、に切り替えて、このように見えるために私たちのShellViewModelを変更することから始めてみましょう:

using System.ComponentModel.Composition;
using System.Windows;

[Export(typeof(IShell))]
public class ShellViewModel : IShell
{
    public bool CanSayHello(string name)
    {
        return !string.IsNullOrWhiteSpace(name);
    }

    public void SayHello(string name)
    {
        MessageBox.Show(string.Format("Hello {0}!", name));
    }
} 

ここで注意すべき点がいくつかあります。まず、我々は今、完全にPOCOクラスを使用して作業しています。無INPCはこちら無神経な人。第二に、我々は我々のsayHelloメソッドに入力パラメータを追加しました。最後に、アクションと同じ入力を持つ方法に私達のCanSayHelloプロパティを変更しましたが、ブール戻り値の型を持ちます。それでは、XAMLを見てみましょう:

<UserControl x:Class="Caliburn.Micro.HelloParameters.ShellView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
             xmlns:cal="http://www.caliburnproject.org">
    <StackPanel>
        <TextBox x:Name="Name" />
        <Button Content="Click Me">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <cal:ActionMessage MethodName="SayHello">
                        <cal:Parameter Value="{Binding ElementName=Name, Path=Text}" />
                    </cal:ActionMessage>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
    </StackPanel>
</UserControl> 

私たちのマークアップは今1修飾を有する:私たちは、バインディングのElementNameを使用ActionMessageの一部としてパラメータを宣言しました。あなたが望む任意の数のパラメータを持つことができます。値はDependencyPropertyにあるので、すべての標準的な結合機能がパラメータに適用されます。私はあなたがBlend内のすべてのこれを行うことができます言及しましたか?

これについていいです一つのことは、すべての時間パラメータの値が変更され、我々は(この場合はCanSayHello)アクションに関連したガードメソッドを呼び出し、ActionMessageが接続されているUIを更新するために、その結果を使用しますということです。前方に移動し、アプリケーションを実行します。あなたはそれが前の例と同じように動作していることがわかります。

リテラル値と式を結合することに加えて、あなたはパラメータで使用できる親切 "特別な"値の数があります。これらはあなたの一般的なコンテキスト情報にアクセスするための便利な方法を可能にします:

$EventArgs - あなたのアクションにトリガーのにEventArgsまたは入力パラメータを渡します。注:トリガーが実際に発生していないので、これがガードメソッドの場合はnullになります。
$DataContext - ActionMessageが接続されている要素のデータコンテキストを渡します。これはActionMessage月親VMへの泡が、それに作用する子インスタンスを実行するために必要なマスター/詳細シナリオで非常に有用です。
$source - ActionMessageを引き起こされる実際のFrameworkElementが送信されます。
$view - のViewModelにバインドされているビュー(通常、ユーザーコントロールまたはウィンドウ)。
$executionContext - 上記のすべての情報および多くを含んでいるアクションの実行コンテキスト。これは高度なシナリオで有用です。
$this - アクションが接続されている実際のUI要素。

あなたは"$"で変数を起動する必要がありますが、名前はCMで、大文字と小文字を区別しない方法で処理されています。これらはMessageBinder.SpecialValuesに値を追加することによって拡張することができます。

Note: Using Special Values like $this or a Named Element

あなたがプロパティを指定しない場合、CMは特定の制御規則で指定されたデフォルトの1を使用します。テキストボックスのデフォルト値はテキストにしながら、ボタンの場合、そのプロパティは、代わりに$そこで別の名前のコントロールへの参照を使用するときに同じことが起こるなど、のSelectedItemに、「のDataContext」にセレクタを発生します。次:<ボタンCAL:Message.Attachは="= MyAction(someTextBox)をクリックして"/> MyActionに「someTextBox」という名前のテキストボックスに含まれるテキストを渡すためにCMを引き起こします。実際の制御は、アクションに渡されることはありません理由は、条約がそれを落胆させVMは直接、UI要素に対処することはありませんということです。コントロール自体は簡単とにかくパラメータを設定するために、(System.Windows.Interactivityに基づいて)拡張構文を使用して、またはパーサーをカスタマイズアクセスすることができること、しかし、注意してください。

Word to the Wise

パラメータは、便利な機能です。彼らは非常に強力であり、いくつかのトリッキーなスポットのあなたを助けることができますが、彼らは簡単に悪用されることができます。個人的に、私は最も簡単なシナリオでパラメータを使用します。彼らは私のためにうまく働いている場所の一つは、ログインフォームです。前述したように別のシナリオでは、マスター/詳細動作です。

さて、あなたは本当に邪悪な何かを見たいですか?これに戻ってあなたのXAMLを変更します。

<UserControl x:Class="Caliburn.Micro.HelloParameters.ShellView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel>
        <TextBox x:Name="Name" />
        <Button x:Name="SayHello" 
                Content="Click Me" />
    </StackPanel>
</UserControl>

アプリケーションを実行すると、CMの規則があってもActionMessageパラメータを理解していることをあなたのために確認させていただきます。今後、より多くの規則を説明しますが、あなたは、これらの規則は、大文字と小文字が区別され、さらには前に述べた「特別な」値を検出することができることを知って幸せでなければなりません。

Action Bubbling

さて、ActionMessageバブリングを示す単純なマスター/詳細シナリオを見て、しかし、のはより多くの開発者に優しいとなるように設計されている省略記法でそれをやらせることができます。我々は、モデルという名前のシンプルな新しいクラスを追加することから始めましょう:

using System;

public class Model
{
    public Guid Id { get; set; }
}

そして、我々はこれまで私たちのShellViewModelを変更します:

using System;
using System.ComponentModel.Composition;

[Export(typeof(IShell))]
public class ShellViewModel : IShell
{
    public BindableCollection<Model> Items { get; private set; }

    public ShellViewModel()
    {
        Items = new BindableCollection<Model>{
            new Model { Id = Guid.NewGuid() },
            new Model { Id = Guid.NewGuid() },
            new Model { Id = Guid.NewGuid() },
            new Model { Id = Guid.NewGuid() }
        };
    }

    public void Add()
    {
        Items.Add(new Model { Id = Guid.NewGuid() });
    }

    public void Remove(Model child)
    {
        Items.Remove(child);
    }
}

現在、私たちのシェルは、コレクションから追加または削除する機能とともに、モデルインスタンスのコレクションを持っています。 Removeメソッドは、型モデルの単一のパラメータを取ることに注意してください。それでは、ShellViewを更新しましょう:

<UserControl x:Class="Caliburn.Micro.BubblingAction.ShellView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:cal="http://www.caliburnproject.org">
    <StackPanel>
        <ItemsControl x:Name="Items">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Button Content="Remove"
                                cal:Message.Attach="Remove($dataContext)" />
                        <TextBlock Text="{Binding Id}" />
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
        <Button Content="Add"
                cal:Message.Attach="Add" />
    </StackPanel>
</UserControl>

Message.Attach

注意すべき最初の事は私達が私達のActionMessagesを宣言するためのより多くのXAML - 開発者向けのメカニズムを使用していることです。 Message.Attachプロパティは、そのテキスト入力を受け取り、あなたが以前に見てきたフルInteraction.Trigger/ ActionMessageに変換する簡単なパーサによって支えられています。あなたはデザイナーで、主にXAMLエディタではなく、作業している場合、あなたはMessage.Attachを好きになるだろう。どちらMessage.Attach宣言がメッセージを送信する必要のあるイベントを指定していることに注意してください。あなたがイベントをオフのままにした場合、パーサーは、トリガに使用するデフォルトのイベントを決定するためにConventionManagerを使用します。ボタンの場合は、クリックします。あなたは、常に粗いの明示的なことができます。ここに私たちの削除メッセージの完全な構文は、我々はすべてを宣言した場合は次のようになります:

<Button Content="Remove"
        cal:Message.Attach="[Event Click] = [Action Remove($dataContext)]" />

我々はMessage.Attach構文に再書き込み、当社のパラメータ化のsayHelloアクションにあったとします。それは次のようになります。

<Button Content="Click Me"
        cal:Message.Attach="[Event Click] = [Action SayHello(Name.Text)]" />

しかし、我々はまた、パーサのいくつかのスマートなデフォルトを活用し、このようにそれを行うことができます:

<Button Content="Click Me"
        cal:Message.Attach="SayHello(Name)" />

あなたは同様にパラメータとしてリテラルを指定しても、セミコロンで区切って複数のアクションを宣言することができます。

<Button Content="Let's Talk"
        cal:Message.Attach="[Event MouseEnter] = [Action Talk('Hello', Name.Text)]; [Event MouseLeave] = [Action Talk('Goodbye', Name.Text)]" />

WARNING 本格的な式パーサーにこの機能を拡張するために私に尋ねたもの開発者が戻っ取り出し、...で配られます。 Message.AttachはXAMLにコードを詰め込みではありません。それは目的が何のメッセージがViewModelにに送信するときに/宣言するため合理化の構文を提供することです。これを乱用しないでください。

あなたがまだの場合は、アプリケーションを実行します。あなたが持っていた疑問がうまくいけば、あなたはCMが自動的にパラメータの型変換を行うことで、メッセージが他の私が指摘したいと思いアドバタイズ:)何かのような作品をバブリングすることを見たとき残りの部分に配置されます。したがって、たとえば、あなたがキャスティングの問題のいずれかを恐れることなくSystem.DoubleパラメータにTextBox.Textポンプすることができます。

そこで、我々はリテラル、要素のバインディングと特殊な値を持つパラメータの使用を含め、ActionMessageでInteraction.Triggersを使用して説明してきました。 Action.Target、Action.TargetWithoutContext、Bind.ModelまたはView.Model:私たちはあなたのニーズ/アーキテクチャスタイルに応じて行動目標を設定するさまざまな方法を説明してきました。また、ActionMessageのバブリング性質の例を見て、合理化Message.Attach構文を使用してデモ。すべての道に沿って私たちもアクションで規則の様々な例を見てきました。今、私たちはまだ...コルーチン説明していないActionMessageの最終的なキラー機能があります。しかし、それは次の時間まで待つ必要があります。

Referenced Samples

  • Caliburn.Micro.HelloExplicitAction
  • Caliburn.Micro.ViewFirst
  • Caliburn.Micro.HelloParameters
  • Caliburn.Micro.BubblingAction