コントロールテンプレートのテンプレートバインディング
-
08-10-2019 - |
質問
次のコントロールテンプレートがあります。
テンプレートバインディングを使用して、コントロールテンプレートの画像制御のソースプロパティを設定したいと思います。
ただし、これはボタン制御用のコントロールテンプレートであり、ボタン制御にはソースプロパティがないため、この場合はテンプレートバインディングを使用できません。
<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>
他のヒント
テンプレートバインディングは軽量の「バインディング」であり、ターゲットプロパティに関連付けられた既知のタイプコンバーターを使用して自動的にタイプ変換(ストリングURIをBitMapsourceインスタンスに変換するなど)を自動的にタイプ変換するなど、従来のバインディングのいくつかの機能をサポートしません。
次のコードは適切に機能します:
<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>
私はあなたの問題をよく理解しているかどうかはわかりませんが、なぜContentSpresenterを使用してみませんか?これにより、画像のコードをより高いレベルで移動できます。
<ControlTemplate x:Key="BtnTemplate" TargetType="Button">
...
<ContentPresenter/>
</ControlTemplate>
...
<Button Template="{StaticResource BtnTemplate}">
<Image .../>
</Button>
所属していません StackOverflow