Связывание шаблона в шаблоне управления
У меня есть следующий шаблон управления.
Я хочу установить свойство источника для элемента управления изображением в шаблоне элемента управления, используя привязку шаблона.
Но так как это шаблон элемента управления для кнопки и элемент управления кнопки не имеет свойства источника, я не могу использовать 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>
Поскольку я должен установить разные изображения для разных экземпляров кнопки, я не могу жестко прописать путь.
Пожалуйста, дайте мне знать, как справиться с этой ситуацией.
4 ответа
Я бы предложил использовать динамические ресурсы, например, определить шаблон следующим образом:
<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 - это легкая "привязка", она не поддерживает некоторые функции традиционного Binding, такие как автоматическое преобразование типов с использованием известных преобразователей типов, связанных со свойством target (например, преобразование строкового 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>
Я не уверен, что хорошо понял вашу проблему, но почему вы не используете ContentPresenter? Это позволяет переместить код вашего изображения на более высокий уровень.
<ControlTemplate x:Key="BtnTemplate" TargetType="Button">
...
<ContentPresenter/>
</ControlTemplate>
...
<Button Template="{StaticResource BtnTemplate}">
<Image .../>
</Button>