2011-01-09 3 views
17

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

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

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

Поскольку я должен установить разные изображения для разных экземпляров кнопки, я также не могу указать путь.

Пожалуйста, дайте мне знать, как справиться с этой ситуацией.

ответ

28

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

<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> 
+1

Можно ли использовать кнопку в гораздо более сжатой форме? Как ? Я поражен этим, не могли бы вы мне помочь? http://stackoverflow.com/q/13464735/640607 – Shankar

2

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

я использовал свойство тега, но это не работает. Source = "{TemplateBinding Tag}" и при создании кнопки Tag = "Temp.jpg", но это не сработает. Я хочу установить источник только в XAML no codebehind. Кроме того, тег не может быть хорошей идеей, так как в элементе controltemplate может быть много элементов управления, для которых я хотел бы установить несколько свойств во время создания объекта. – Sam

+0

Это не работает, потому что 'Source' имеет тип' ImageSource', а «Temp.jpg» - это «строка». Вам нужно будет использовать конвертер для преобразования строк в ImageSources, как это делает элемент управления 'Image'. –

5

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

+0

есть ли другой способ сделать это, а не иметь тег.? Я беспокоюсь за это, позже у меня может быть несколько элементов управления в моем шаблоне управления, и я бы хотел установить свойства во время создания объекта. Но поскольку Tag уже используется, я не смогу использовать его снова. – Sam

+0

Вы можете сделать то, что предлагает Кент. Сделайте из кнопки и создайте свой собственный элемент управления. Добавьте свое собственное свойство зависимостей и используйте его, используя тег. – biju

+0

. Моя проблема была немного иной, чем исходная запись, но это было единственное решение, которое сделало трюк.Я потратил все утро на это, потому что ошибки в одном ресурсном словаре препятствовали загрузке пользовательского интерфейса несколькими дизайнерами xaml в нашем приложении. Серьезно, спасибо. – CodeOtaku

1

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

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