web-dev-qa-db-ja.com

イベント処理のためにWPFのリソースディクショナリの背後にコードを設定することは可能ですか?

WPFのリソースディクショナリの背後にコードを設定することは可能ですか?たとえば、ボタンのユーザーコントロールでは、XAMLで宣言します。ボタンクリックのイベント処理コードは、コントロールの背後のコードファイルで実行されます。ボタン付きのデータテンプレートを作成する場合、リソースディクショナリ内のボタンクリックのイベントハンドラコードをどのように記述できますか。

143
Crippeoblade

あなたが求めているのは、ResourceDictionaryの分離コードファイルが必要だと思います。完全にこれを行うことができます!実際、ウィンドウの場合と同じ方法で行います。

MyResourceDictionaryというResourceDictionaryがあるとします。 MyResourceDictionary.xamlファイルで、次のようにルート要素にx:Class属性を追加します。

<ResourceDictionary xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
                    x:Class="MyCompany.MyProject.MyResourceDictionary"
                    x:ClassModifier="public">

次に、次の宣言を使用してMyResourceDictionary.xaml.csというコードビハインドファイルを作成します。

namespace MyCompany.MyProject
{
    partial class MyResourceDictionary : ResourceDictionary
    { 
       public MyResourceDictionary()
       {
          InitializeComponent();
       }     
       ... // event handlers ahead..
    }
}

これで完了です。コードビハインドには、メソッド、プロパティ、イベントハンドラなど、必要なものを何でも配置できます。

== Windows 10アプリの更新==

そして、あなたが[〜#〜] uwp [〜#〜]で遊んでいる場合のために、もう一つ注意すべきことがあります:

<Application x:Class="SampleProject.App"
             xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
             xmlns:rd="using:MyCompany.MyProject">
<!-- no need in x:ClassModifier="public" in the header above -->

    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>

                <!-- This will NOT work -->
                <!-- <ResourceDictionary Source="/MyResourceDictionary.xaml" />-->

                <!-- Create instance of your custom dictionary instead of the above source reference -->
                <rd:MyResourceDictionary />

            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>

</Application>
204
ageektrapped

私は「ageektrapped」に同意しません...部分クラスのメソッドを使用するのは良い習慣ではありません。辞書をページから分離する目的は何ですか?

コードビハインドから、次を使用してx:Name要素にアクセスできます。

Button myButton = this.GetTemplateChild("ButtonName") as Button;
if(myButton != null){
   ...
}

カスタムコントロールの読み込み時にコントロールに接続する場合は、OnApplyTemplateメソッドで this を実行できます。これを行うには、OnApplyTemplateをオーバーライドする必要があります。これは一般的な方法であり、スタイルをコントロールから切り離したままにすることができます。 (スタイルはコントロールに依存するべきではありませんが、コントロールはスタイルを持つことに依存するべきです)。

9
Phobis

Gishu-これは「一般的に練習を奨励することではない」ように思えるかもしれませんが、これを行う理由の1つは次のとおりです。

テキストボックスがフォーカスを取得するときの標準的な動作は、コントロールがフォーカスを失ったときと同じ位置にキャレットを配置することです。アプリケーション全体で、ユーザーが任意のテキストボックスにタブを移動して、テキストボックスのコンテンツ全体が強調表示されるようにしたい場合は、リソース辞書に単純なハンドラーを追加するとうまくいきます。

デフォルトのユーザーインタラクション動作をそのままの動作と異なるものにする他の理由は、リソースディクショナリのコードビハインドの良い候補のようです。

アプリケーション機能固有のものは、リソースディクショナリの背後にあるコードに含めるべきではないことに完全に同意します。

5
Pete Maher

XAMLは、コードを含まないオブジェクトグラフを構築するためのものです。
データテンプレートは、カスタムユーザーオブジェクトが画面上でどのようにレンダリングされるかを示すために使用されます(リストボックスアイテムの場合など)動作は、データテンプレートの専門分野の一部ではありません。ソリューションを再描画...

0
Gishu