Search code examples
wpfxamldata-bindingexpression-blend

Bind template data field to instance (via "Use a custom path expression"?)


I have created a template of a button, which contains an Image and a TextBlock. Since I would like to change the appearance of both, I think they need to be in the Template. But, of course, not every instance of this template should present the same text and image.

Until now, i found a promising property called "Use a custom path expression" at the "Text" / "Source"-value filed of the TextBlock / Image at:

Data Binding... > Element Property > Use a custom path expression

I would now like to set this value at the instances of the button. I already tried to manually insert a myText="Lorem Ipsum" in the XAML of the Button, but that does not seem to work.

Thank you in advance for your help!

Update: This is, how the XAML looks like:

<TextBlock [...] Text="{Binding myText, ElementName={x:Null}, FallbackValue=Lorem}"/>

How do I access this or modify this, so it can be accessed?

Update 2: There already exist bindings for the TextBlock and the Image. At the moment, the XAML of the Button looks like that:

<s:SurfaceButton Command="{Binding SearchCustomCommand}" Style="{DynamicResource BasicButton}">
    <StackPanel Orientation="Vertical" Height="60" Width="48" IsHitTestVisible="False">
        <Image Source="{StaticResource ImageSourceToolboxSearchIcon}" 
            [...]
            Stretch="Uniform" />
        <TextBlock Text="{lex:LocText ToolboxButtonSearchesCustom}" 
            FontFamily="{DynamicResource button.font}" 
            [...]
            FontSize="{DynamicResource button.size}" 
            Foreground="{DynamicResource button.color.default}"/>
    </StackPanel>
</s:SurfaceButton>

I would now like to extract the Image and Textbox to the template (which also already exists), so I could refrence the Button in a way like this (whith all the Information about sizes and colors etc in the template and only the reference to the resource in the actual instance of the button - to be able to change the image/text for echt button seperately):

<s:SurfaceButton
    Command="{Binding SearchPopularCommand}"
    Style="{DynamicResource ToolboxButtonBig}"
    ImageSource="{StaticResource ImageSourceToolboxSearchIcon}"
    TextBlockSource="{lex:LocText ToolboxButtonSearchesCustom}"/>

I already copied the whole XAML for the StackPanel and the included TextBlock and Image to the Template. Now those are shown on every Button (which is fine), but i can't change the contents of them.

I'm sorry if the description is quite poor - I'm rather new to WPF...

Update 3: After some further research, I found questions similar to mine - which obviously describe the problem better than I could:


Solution

  • it is not necessary to edit button's template to insert image and text, you can set Button.Content property like this:

    <Button>
            <Button.Content>
                <StackPanel Orientation="Horizontal">
                    <Image Source="../Images/image.png"/>
                    <TextBlock Text="Lorem Ipsum"/>
                </StackPanel>
            </Button.Content>
        </Button>
    

    and it will work well. example above can be simplified but I inserted it like this for better understanding what is going on.

    EDIT: here are examples how it can be done in two different ways: overwriting template:

    <Button Content="Lorem Ipsum">
            <Button.Template>
                <ControlTemplate TargetType="Button">
                    <StackPanel Orientation="Horizontal">
                        <Image x:Name="ButtonImage" Source="../Images/mouseNotOverImage.png"/>
                        <ContentPresenter Margin="2"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center"
                            RecognizesAccessKey="True" />
                    </StackPanel>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="ButtonImage" Property="Source" Value="../Images/mouseOverImage.png"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Button.Template>
        </Button>
    

    complete button template definition you can find here modifying style:

    <Button>
            <Button.Style>
                <Style TargetType="Button">
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Content">
                                <Setter.Value>
                                    <StackPanel Orientation="Horizontal">
                                        <Image Source="../Images/mouseOverImage.png"/>
                                        <TextBlock Text="Lorem Ipsum"/>
                                    </StackPanel>
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="False">
                            <Setter Property="Content">
                                <Setter.Value>
                                    <StackPanel Orientation="Horizontal">
                                        <Image Source="../Images/mouseNotOverImage.png"/>
                                        <TextBlock Text="Lorem Ipsum"/>
                                    </StackPanel>
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>