私はこれをXAMLで持っています
<ControlTemplate TargetType="{x:Type Button}">
<Image ...>
</ControlTemplate>
C#コードでも同じことを実現したい。どうすればこれを達成できますか?
ControlTemplate ct = new ControlTemplate();..
Image img = new Image();..
次に、この画像をコントロールテンプレートに割り当てる方法は?私たちはこれを行うことができますか、ここで何か概念が欠けていますか?
コードビハインドでテンプレートを作成することはお勧めできません。理論的には、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を使用するのと同じです。
その文は間違っているだけで、「する必要はありません」。
実行時にテンプレートを割り当てる場合、必要に応じて読み込むことができるリソースとしてテンプレートを定義します。
Edit:ドキュメントによると FrameworkElementFactory
は非推奨です:
このクラスは、ControlTemplateやDataTemplateなどのFrameworkTemplateのサブクラスであるテンプレートをプログラムで作成するための非推奨の方法です。このクラスを使用してテンプレートを作成するときに、テンプレート機能のすべてが利用できるわけではありません。プログラムでテンプレートを作成する推奨方法は、XamlReaderクラスのLoadメソッドを使用して、文字列またはメモリストリームからXAMLを読み込むことです。
この推奨事項はとても良いアイデアだろうか。個人的には、文字列とXamlReader
を使用してテンプレートを回避することができれば、テンプレートをXAMLのリソースとして定義します。
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 を含める必要があることに注意してください。含めなかった場合、ランタイム例外が発生します。基本的に、テンプレートに必要な名前空間を配置する必要があります。
ボタンの画像のみを変更する必要がある場合は、1つのことを行うことができます。
XAMLでは、ボタンテンプレートでこれを使用します
CurrentButtonImageのプロパティの変更時に、ボタンのイメージを(コードビハインドで)使用して更新します
CurrentImagePropertyChangedhandler(....,...)
{
switch(CurrentButtonImage)
{
case "Image1" :
this._ButtonImage.Fill = (DrawingBrush)csd.FindResource("Image1DrawingBrush");
break;
}
}