Привязка шаблона в шаблоне управления - PullRequest
19 голосов
/ 09 января 2011

У меня есть следующий шаблон управления.

Я хочу установить свойство источника для элемента управления изображением в элементе управления. шаблон с помощью привязки шаблона.

Но так как это шаблон управления для кнопки управления, а кнопка управления не есть свойство source, я не могу использовать 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 ]

30 голосов
/ 09 января 2011

Я бы предложил использовать динамические ресурсы, например, определить шаблон следующим образом:

<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>
5 голосов
/ 09 января 2011

TemplateBinding - это легкое «связывание», оно не поддерживает некоторые функции традиционного связывания, такие как автоматическое преобразование типов с использованием известных преобразователей типов, связанных со свойством 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>

2 голосов
/ 09 января 2011

Вы действительно не сказали, как вы ожидаете, что потребители вашей кнопки установят источник. Например, вы можете использовать свойство 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>
1 голос
/ 09 января 2011

Я не уверен, что хорошо понял вашу проблему, но почему вы не используете ContentPresenter? Позволяет переместить код вашего изображения на более высокий уровень.

<ControlTemplate x:Key="BtnTemplate" TargetType="Button">
  ...
  <ContentPresenter/>
</ControlTemplate>
...
<Button Template="{StaticResource BtnTemplate}">
  <Image .../>
</Button>
...