Wpf 将模板数据字段绑定到实例(通过“使用自定义路径表达式”?)

Wpf 将模板数据字段绑定到实例(通过“使用自定义路径表达式”?),wpf,xaml,data-binding,expression-blend,Wpf,Xaml,Data Binding,Expression Blend,我已经创建了一个按钮模板,其中包含一个图像和一个文本块。因为我想改变两者的外观,所以我认为它们需要在模板中。但是,当然,并非此模板的每个实例都应显示相同的文本和图像 到目前为止,我在TextBlock/Image的“Text”/“Source”-值字段中找到了一个很有希望的属性,名为“使用自定义路径表达式”,位于: Data Binding... > Element Property > Use a custom path expression 我现在想在按钮的实例处设置此值。我已

我已经创建了一个按钮模板,其中包含一个图像和一个文本块。因为我想改变两者的外观,所以我认为它们需要在模板中。但是,当然,并非此模板的每个实例都应显示相同的文本和图像

到目前为止,我在TextBlock/Image的“Text”/“Source”-值字段中找到了一个很有希望的属性,名为“使用自定义路径表达式”,位于:

Data Binding... > Element Property > Use a custom path expression
我现在想在按钮的实例处设置此值。我已经尝试在按钮的XAML中手动插入一个
myText=“Lorem Ipsum”
,但这似乎不起作用

提前感谢您的帮助

更新:这是XAML的外观:

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

如何访问或修改此文件,以便可以访问

更新2:已经存在文本块和图像的绑定。目前,按钮的XAML如下所示:

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

我现在想将图像和文本框提取到模板中(模板也已经存在),这样我就可以像这样引用按钮(模板中关于尺寸和颜色等的所有信息以及按钮实际实例中对资源的引用-能够单独更改echt按钮的图像/文本):


我已经将StackPanel的整个XAML以及包含的文本块和图像复制到模板中。现在这些都显示在每个按钮上(这很好),但我无法更改它们的内容

我很抱歉,如果描述很差-我是WPF的新手

更新3:在进一步研究之后,我发现了与我类似的问题-显然,这些问题比我能更好地描述问题:


插入图像和文本无需编辑按钮的模板,您可以设置按钮。内容属性如下:

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

上面的例子可以简化,但我这样插入它是为了更好地理解正在发生的事情

编辑: 以下是如何通过两种不同方式实现的示例: 覆盖模板:

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

您可以找到完整的按钮模板定义 修改样式:

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

您的第一个选择是定义一个(或多个)样式,例如


第二个选项是使用Blend创建默认按钮样式的副本并编辑该样式

<Window.Resources>
    <Style x:Key="MyButton" TargetType="{x:Type Button}" >
        <Setter Property="Content">
            <Setter.Value>
                <Grid>
                    <TextBlock Text="Test"/>
                </Grid>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="ButtonFocusVisual">
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate>
                    <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#F3F3F3" Offset="0"/>
        <GradientStop Color="#EBEBEB" Offset="0.5"/>
        <GradientStop Color="#DDDDDD" Offset="0.5"/>
        <GradientStop Color="#CDCDCD" Offset="1"/>
    </LinearGradientBrush>
    <SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/>
    <Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
        <Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
        <Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="HorizontalContentAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Padding" Value="1"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Themes:ButtonChrome x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RenderDefaulted="{TemplateBinding IsDefaulted}" SnapsToDevicePixels="true">


                        <!-- put your text and image here -->

                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>

                    </Themes:ButtonChrome>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsKeyboardFocused" Value="true">
                            <Setter Property="RenderDefaulted" TargetName="Chrome" Value="true"/>
                        </Trigger>
                        <Trigger Property="ToggleButton.IsChecked" Value="true">
                            <Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="#ADADAD"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<Grid>
    <Button Content="Button" HorizontalAlignment="Left" Margin="167,151,0,0" VerticalAlignment="Top" Width="75" Style="{DynamicResource MyButtonStyle}"/>
</Grid>


第三个选项是基于默认按钮样式创建自定义控件。然后您可以创建依赖项属性并使用模板绑定。

谢谢您的回答!我想我需要在模板中设置图像和文本,因为我想更改它们在按钮不同状态下的外观(如“正常”、“鼠标悬停”等)您可以在VisualStates(模板内)中使用图像的源代码进行操作,您需要一个示例来实现吗?如果您能给我一个小示例来实现这一点,那将非常好:)在编辑块下添加了示例。抱歉,stackoverflow代码插入逻辑很愚蠢(嫉妒)谢谢你的回答!我想你发布的第一个选项将为我提供一个静态解决方案,其中图像绑定到模板,对吗?我试图澄清我的问题(请参阅上次更新)为了澄清我需要某种动态解决方案,我可以在模板的每个实例中插入不同的内容。没有什么可以阻止你创建多个样式MyButton1、MyButton2等。如果你需要绑定到视图模型,那么你需要一个自定义控件。
<Window.Resources>
    <Style x:Key="MyButton" TargetType="{x:Type Button}" >
        <Setter Property="Content">
            <Setter.Value>
                <Grid>
                    <Image .../>
                    <TextBlock Text="Test"/>
                </Grid>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<Grid>
    <Button Style="{StaticResource MyButton}" />
</Grid>
<Window.Resources>
    <Style x:Key="MyButton" TargetType="{x:Type Button}" >
        <Setter Property="Content">
            <Setter.Value>
                <Grid>
                    <TextBlock Text="Test"/>
                </Grid>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="ButtonFocusVisual">
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate>
                    <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#F3F3F3" Offset="0"/>
        <GradientStop Color="#EBEBEB" Offset="0.5"/>
        <GradientStop Color="#DDDDDD" Offset="0.5"/>
        <GradientStop Color="#CDCDCD" Offset="1"/>
    </LinearGradientBrush>
    <SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/>
    <Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
        <Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
        <Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="HorizontalContentAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Padding" Value="1"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Themes:ButtonChrome x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RenderDefaulted="{TemplateBinding IsDefaulted}" SnapsToDevicePixels="true">


                        <!-- put your text and image here -->

                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>

                    </Themes:ButtonChrome>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsKeyboardFocused" Value="true">
                            <Setter Property="RenderDefaulted" TargetName="Chrome" Value="true"/>
                        </Trigger>
                        <Trigger Property="ToggleButton.IsChecked" Value="true">
                            <Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="#ADADAD"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<Grid>
    <Button Content="Button" HorizontalAlignment="Left" Margin="167,151,0,0" VerticalAlignment="Top" Width="75" Style="{DynamicResource MyButtonStyle}"/>
</Grid>