35

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

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

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

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

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

4

3 に答える 3

34

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

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

プロパティの割り当ては、とを使用する必要があるため、非常に回りくどいSetValueですSetBinding

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

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

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

そのステートメントはちょうど間違っています、私たちは「しなければならない」わけではありません。


実行時にテンプレートを割り当てる場合は、必要に応じてロードできるリソースとしてテンプレートを定義します。


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

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

この推薦はそんなに良い考えではないかと思います。個人的には、文字列とを使用してテンプレートを定義することを回避できる場合は、テンプレートをXAMLのリソースとして定義しますXamlReader

于 2011-04-22T13:08:03.717 に答える
25

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にはLoadメソッドもあります。これは、主にストリーム、XAML、またはXMLリーダーに使用されます。 必要なControlTemplate、Border、およびその他のコントロールがそこで定義されているため、XML名前空間 http://schemas.microsoft.com/winfx/2006/xaml/presentationを含める必要があることに注意してください。これを含めなかった場合、実行時例外が発生します。基本的に、テンプレートに必要な名前空間を配置する必要があります。

于 2011-04-22T12:53:08.210 に答える
0

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

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

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

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

CurrentImagePropertyChangedhandler(....,...)  
{  
    switch(CurrentButtonImage)  
    {  
        case "Image1" :  
          this._ButtonImage.Fill = (DrawingBrush)csd.FindResource("Image1DrawingBrush");
          break;
    }
}
于 2011-04-22T12:56:05.460 に答える