134

WPFでリソースディクショナリの背後にコードを設定することは可能ですか。たとえば、ボタンのユーザーコントロールでは、XAMLでそれを宣言します。ボタンクリックのイベント処理コードは、コントロールの背後のコードファイルで行われます。ボタンを使用してデータテンプレートを作成する場合、リソースディクショナリ内でボタンクリックのイベントハンドラコードを作成する方法を教えてください。


  • これを行う正しい方法は、コマンドを使用することです。また、ボタンを有効または無効にする機能もありますが、一部の回答ではハックの匂いがするという方法もあります。 - Aran Mulholland

4 답변


195

私が求めているのは、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もう1つ注意が必要なことがあります。

<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>


  • ageektrappedの回答への補足として:あなたのコードビハインドクラスの完全修飾名をx:Class属性に入れるようにしてください。x:Class="MyCompany.MyProject.MySubFolder1.MyResourceDictionary"それ以外の場合は、単にx:Class =" MyResourceDictionary"を入力しただけでは、xamlパーサーはクラスを見つけることができません。 - viggity
  • コードビハインドクラスのデフォルトコンストラクタを必ず提供し、InitializeComponent()を呼び出すようにしてください。 (私の場合、リソースディクショナリのエクスポートにMEFを使用していました。) - Scott Whitlock
  • 支持コメントのコードスニペットを更新しました。答えを完成させるために必要だと感じました。よくある間違いです。私は今それをした:)あなたがそれを好まないならば元に戻す。答えてくれてありがとう。 - Gishu
  • (少なくともwp8.1では)これはもはや有効ではなく、あなたはあなたのリソース辞書が参照するカスタムユーザーコントロールを作成しなければならないことに注意してください。 - Jared
  • ResourceDictionaryのXAMLファイルの[ビルド]アクションを[Page]に設定する必要があります。そうしないと、InitializeComponent()呼び出しでコンパイルできません。 (ResourceDictionary XAMLファイルは通常、デフォルトで"リソース"に設定されています。) - user1454265

9

"ageektrapped"には同意しません...部分クラスのメソッドを使用するのはお勧めできません。それでは、辞書をページから分離する目的は何でしょうか。

分離コードからは、次のようにしてx:Name要素にアクセスできます。

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

できるよこのカスタムコントロールがロードされたときにコントロールに接続する場合は、OnApplyTemplateメソッドを使用します。これを行うには、OnApplyTemplateをオーバーライドする必要があります。これは一般的な方法であり、スタイルをコントロールから切り離したままにしておくことができます。 (スタイルはコントロールに依存しないようにする必要がありますが、コントロールはスタイルを持つことに依存する必要があります)。


  • 恐怖私は辞書をページから分離する目的はメインページxamlの再利用性と読みやすさにあると思います。上記の解決策も私のために働いた。 - cleftheris

5

紀州 - これは「一般的には奨励されない練習」であるように思われるかもしれませんが、ここであなたがそれをしたいと思うかもしれない1つの理由があります:

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

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

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


0

XAMLは、コードを含まないオブジェクトグラフを作成するためのものです。

データテンプレートは、カスタムユーザオブジェクトが画面上にどのように表示されるかを示すために使用されます。(たとえば、リストボックス項目の場合)ビヘイビアは、データテンプレートの専門分野の一部ではありません。解決策を描き直す...


  • 結論:コードビハインドでリソースdicを使用することをお勧めします。私はそれを使ったことがない、疑っている。 - Shimmy
  • 私はしたくない - 私にはそれは正しいとは思わない。辞書は特定のキーの値を返すべきです。 OPの場合は、データテンプレートにコードをバンドルするのではなく、別の方法を試してみてください。たとえば、Commandモデルを使用してください。 diff solnを推奨するには、OPの問題に関する詳細情報が必要です。 - Gishu
  • 全くそう思わない。 MVVMでは、コードビハインドが非常に便利なシナリオが1つあります。それは、添付プロパティの開発です。コードビハインドを使用して作業してから、添付プロパティに移植します。あなたがマンハッタンの大きさの頭脳を持っていない限り、これは単に一からアタッチされたプロパティを開発するよりはるかに速いです。 - Contango

リンクされた質問


関連する質問

最近の質問