次のコントロールテンプレートがあります。
テンプレートバインディングを使用して、コントロールテンプレートの画像コントロールのソースプロパティを設定したいと思います。
しかし、これはボタンコントロールのコントロールテンプレートであり、ボタンコントロールにはソースプロパティがないため、この場合はTemplateBindingを使用できません。
<ControlTemplate x:Key="BtnTemplate" TargetType="Button">
<Border CornerRadius="5" Margin="15" Cursor="Hand">
<StackPanel>
<Image Name="Img" Style="{StaticResource ImageStyle}" Source="temp.jpg" Height="100" Width="100" Margin="5"></Image>
<Label Content="{TemplateBinding Content}" Background="Transparent" Margin="2"></Label>
</StackPanel>
</Border>
</ControlTemplate>
ボタンのインスタンスごとに異なる画像を設定する必要があるため、パスもハードコーディングできません。
この状況への対処方法を教えてください。
動的リソースを使用することをお勧めします。テンプレートを次のように定義します。
<ControlTemplate x:Key="buttonTemplate" TargetType="Button">
<Border CornerRadius="5" Margin="15" Cursor="Hand">
<StackPanel Orientation="Horizontal" Background="Yellow">
<Image Source="{DynamicResource ResourceKey=Img}" Height="100" Width="100" Margin="5"></Image>
<Label Content="{TemplateBinding Content}" Background="Transparent" Margin="2"></Label>
</StackPanel>
</Border>
</ControlTemplate>
次のように使用します。
<Button Content="Button" Template="{StaticResource ResourceKey=buttonTemplate}">
<Button.Resources>
<ImageSource x:Key="Img">SomeUri.png/</ImageSource>
</Button.Resources>
</Button>
TemplateBindingは軽量の「バインディング」であり、ターゲットプロパティに関連付けられた既知の型コンバーターを使用した自動型変換(文字列URIをBitmapSourceインスタンスに変換するなど)など、従来のBindingの一部の機能をサポートしていません。
次のコードは正しく動作します。
<Window x:Class="GridScroll.Window2"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
Title="Window2">
<Window.Resources>
<Style TargetType="{x:Type Button}" x:Key="ButtonStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="5" Margin="15" Cursor="Hand" Background="Red">
<StackPanel Orientation="Horizontal" Background="White">
<Image Name="Img" Source="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}" Margin="5"></Image>
<Label Content="{TemplateBinding Content}" Margin="2"></Label>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel Orientation="Horizontal">
<Button Style="{StaticResource ButtonStyle}" Tag="a.jpeg" Content="a"/>
<Button Style="{StaticResource ButtonStyle}" Tag="b.png" Content="b"/>
</StackPanel>
ボタンの消費者がソースを設定することをどのように期待するかについては、実際には言っていません。たとえば、Button.Tag
プロパティを使用して、テンプレートでそれにバインドできます。または、独自のコントロールを定義することもできます。
public class ImageButton : Button
{
// add Source dependency property a la Image
}
そしてテンプレート:
<ControlTemplate TargetType="ImageButton">
<Border CornerRadius="5" Margin="15" Cursor="Hand">
<StackPanel>
<Image Name="Img" Style="{StaticResource ImageStyle}" Source="{TempateBinding Source}" Height="100" Width="100" Margin="5"></Image>
<Label Content="{TemplateBinding Content}" Background="Transparent" Margin="2"></Label>
</StackPanel>
</Border>
</ControlTemplate>
私はあなたの問題をよく理解したかわかりませんが、なぜContentPresenterを使用しないのですか?それはあなたの画像のコードをより高いレベルで移動することを可能にします。
<ControlTemplate x:Key="BtnTemplate" TargetType="Button">
...
<ContentPresenter/>
</ControlTemplate>
...
<Button Template="{StaticResource BtnTemplate}">
<Image .../>
</Button>