web-dev-qa-db-ja.com

コードでコントロールテンプレートを設定する方法は?

私はこれをXAMLで持っています

<ControlTemplate TargetType="{x:Type Button}">
    <Image ...>
</ControlTemplate>

C#コードでも同じことを実現したい。どうすればこれを達成できますか?

ControlTemplate ct = new ControlTemplate();..
Image img = new Image();..

次に、この画像をコントロールテンプレートに割り当てる方法は?私たちはこれを行うことができますか、ここで何か概念が欠けていますか?

29
Haris Hasan

コードビハインドでテンプレートを作成することはお勧めできません。理論的には、ControlTemplate.VisualTreeこれは FrameworkElementFactory です。

ControlTemplate template = new ControlTemplate(typeof(Button));
var image = new FrameworkElementFactory(typeof(Image));
template.VisualTree = image;

SetValueSetBindingを使用する必要があるため、プロパティの割り当ては非常に回り道です。

image.SetValue(Image.SourceProperty, ...);

また、(以前に)受け入れられた答えと引用されたものについて:

ControlTemplateをプログラムで設定するのは、XamlReaderクラスを使用する必要があるため、XAMLを使用するのと同じです。

その文は間違っているだけで、「する必要はありません」


実行時にテンプレートを割り当てる場合、必要に応じて読み込むことができるリソースとしてテンプレートを定義します。


Edit:ドキュメントによると FrameworkElementFactory は非推奨です:

このクラスは、ControlTemplateやDataTemplateなどのFrameworkTemplateのサブクラスであるテンプレートをプログラムで作成するための非推奨の方法です。このクラスを使用してテンプレートを作成するときに、テンプレート機能のすべてが利用できるわけではありません。プログラムでテンプレートを作成する推奨方法は、XamlReaderクラスのLoadメソッドを使用して、文字列またはメモリストリームからXAMLを読み込むことです。

この推奨事項はとても良いアイデアだろうか。個人的には、文字列とXamlReaderを使用してテンプレートを回避することができれば、テンプレートをXAMLのリソースとして定義します。

29
H.B.

http://www.eggheadcafe.com/sample-code/SilverlightWPFandXAML/73fdb6a2-6044-4c43-8766-afa12618ddc1/set-controltemplate-programmatically.aspx

ControlTemplateをプログラムで設定するのは、XamlReaderクラスを使用する必要があるため、XAMLを使用するのと同じです。たとえば、ボタンのテンプレートを設定するコードは、ボタンのテンプレートをロード後に設定することを想定しています。

private void Button_Loaded(object sender, RoutedEventArgs e) {
    var button = sender as Button;
    string template =
        "<ControlTemplate xmlns='http://schemas.Microsoft.com/winfx/2006/xaml/presentation'
            TargetType=\"Button\">" +
            "<Border>" +
                 "<ContentPresenter/>" +
            "</Border>" +
        "</ControlTemplate>";
    button.Template = (ControlTemplate)XamlReader.Parse(template);
}

テンプレートのXAMLコードを指定するために文字列を使用したため、XamlReaderのParseメソッドを使用できます。 XamlReaderには、主にストリーム、XAML、またはXMLリーダーに使用されるLoadメソッドもあります。必要なControlTemplate、Border、およびその他のコントロールがそこに定義されているため、XML名前空間 http://schemas.Microsoft.com/winfx/2006/xaml/presentation を含める必要があることに注意してください。含めなかった場合、ランタイム例外が発生します。基本的に、テンプレートに必要な名前空間を配置する必要があります。

23
obenjiro

ボタンの画像のみを変更する必要がある場合は、1つのことを行うことができます。

  1. 画像を変更したいとき(bool)を表す依存関係プロパティを作成するか、すべての可能な画像を含む列挙型を作成できます
  2. 画像の列挙{Image1 = 0、Image2 = 1、Image2 = 3}。ボタンに関連付けられるこのタイプの依存プロパティ「CurrentButtonImage」を作成します。

XAMLでは、ボタンテンプレートでこれを使用します

CurrentButtonImageのプロパティの変更時に、ボタンのイメージを(コードビハインドで)使用して更新します

CurrentImagePropertyChangedhandler(....,...)  
{  
    switch(CurrentButtonImage)  
    {  
        case "Image1" :  
          this._ButtonImage.Fill = (DrawingBrush)csd.FindResource("Image1DrawingBrush");
          break;
    }
}
0
Rohit