Enlace de plantilla en la plantilla de control

Tengo la siguiente plantilla de control.

Deseo establecer la propiedad de origen para el control de imagen en la plantilla de control usando Template Binding.

Pero dado que esta es una plantilla de control para el control de botones y el control de botones no tiene propiedad de origen, no puedo usar TemplateBinding en este caso.

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

Como tengo que configurar diferentes imágenes para diferentes instancias de botón, tampoco puedo codificar la ruta.

Hágame saber cómo abordar esta situación.

preguntado el 09 de enero de 11 a las 10:01

4 Respuestas

Sugeriría usar recursos dinámicos, por ejemplo, defina la plantilla de la siguiente manera:

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

Y utilícelo así:

<Button Content="Button" Template="{StaticResource ResourceKey=buttonTemplate}">
    <Button.Resources>
        <ImageSource x:Key="Img">SomeUri.png/</ImageSource>
    </Button.Resources>
</Button>

Respondido el 09 de enero de 11 a las 14:01

¿Es posible utilizar el botón de una manera mucho más concisa? Como ? Estoy impresionado con esto, ¿podrían ayudarme? stackoverflow.com/q/13464735/640607 - Shankar Raju

TemplateBinding es un "enlace" ligero, no admite algunas características del enlace tradicional, como la conversión automática de tipos utilizando los convertidores de tipos conocidos asociados con la propiedad de destino (como convertir el URI de cadena en una instancia de BitmapSource).

El siguiente código puede funcionar correctamente:

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

Respondido el 09 de enero de 11 a las 14:01

¿Hay alguna otra forma de hacerlo en lugar de tener Tag.? Estoy preocupado porque más tarde podría tener múltiples controles en mi plantilla de control y me gustaría establecer las propiedades en el momento de crear el objeto. Pero como la etiqueta ya se usa, no podré usarla nuevamente. - Diana

Puede hacer lo que sugiere Kent. Derive del botón y cree su propio control. Agregue su propiedad de dependencia personalizada y utilícela como yo uso la etiqueta - Biju

Mi problema era ligeramente diferente al de la publicación original, pero esta fue la única solución que funcionó. Pasé toda la mañana en esto, porque los errores en un diccionario de recursos únicos impedían que la interfaz de usuario se cargara en varios diseñadores de xaml en toda nuestra aplicación. En serio, gracias. - CódigoOtaku

Realmente no ha dicho cómo espera que los consumidores de su botón establezcan la fuente. Podrías usar el Button.Tag propiedad, por ejemplo, y luego enlazar con eso en su plantilla. O puede definir su propio control:

public class ImageButton : Button
{
    // add Source dependency property a la Image
}

Y luego la plantilla:

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

Respondido el 28 de Septiembre de 11 a las 04:09

Usé la propiedad de la etiqueta pero eso no funciona. Source = "{TemplateBinding Tag}" y al crear el botón, Tag = "Temp.jpg" pero esto no funciona. Deseo establecer la fuente solo en XAML sin código subyacente. Además, es posible que Tag no sea una buena idea, ya que puede haber muchos controles dentro de la plantilla de control para los que me gustaría establecer algunas propiedades en el momento de la creación del objeto. - Diana

Eso no funciona porque Source es de tipo ImageSourcey "Temp.jpg" es un string. Necesitará usar un convertidor para convertir cadenas a ImageSources, al igual que el Image el control lo hace. - Kent Boogaart

No estoy seguro de haber entendido muy bien su problema, pero ¿por qué no usa ContentPresenter? Permite mover el código de su imagen a un nivel superior.

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

Respondido el 09 de enero de 11 a las 14:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.