wpf 控制模板中的模板绑定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4638741/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 22:28:54  来源:igfitidea点击:

Template Binding in Control template

wpfxamldata-bindingcontroltemplatetemplatebinding

提问by Sam

I have the following control template.

我有以下控制模板。

I wish to set the source property for the image control in the control template using Template Binding.

我希望使用模板绑定在控件模板中设置图像控件的源属性。

But since this is a control template for button control and the button control doesn't have source property, i can't use TemplateBinding in this case.

但是由于这是按钮控件的控件模板,并且按钮控件没有源属性,因此在这种情况下我不能使用 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>

Since i have to set different images for different instances of button, i can't hardcode the path as well.

由于我必须为按钮的不同实例设置不同的图像,因此我也无法对路径进行硬编码。

Please let me know how to tackle this situation.

请让我知道如何处理这种情况。

回答by H.B.

I'd suggest using dynamic resources, e.g. define the template as follows:

我建议使用动态资源,例如定义模板如下:

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

And use it like this:

并像这样使用它:

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

回答by biju

TemplateBinding is a lightweight "binding", it doesn't support some features of traditional Binding, such as automatically type conversion using the known type converters associated with the target property (such as converting the string URI into a BitmapSource instance).

TemplateBinding 是一个轻量级的“绑定”,它不支持传统 Binding 的一些特性,例如使用与目标属性关联的已知类型转换器自动类型转换(例如将字符串 URI 转换为 BitmapSource 实例)。

The following code can work properly:

以下代码可以正常工作:

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

回答by Kent Boogaart

You haven't really said how you expect consumers of your button to set the source. You could use the Button.Tagproperty, for example, and then bind to that in your template. Or you could define your own control:

您还没有真正说明您希望按钮的消费者如何设置源。Button.Tag例如,您可以使用该属性,然后在模板中绑定到该属性。或者您可以定义自己的控件:

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

And then the template:

然后是模板:

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

回答by Kirill Lykov

I'm not sure that I understood your problem very well but why don't you use ContentPresenter? It allows to move the code for your Image at the higher level.

我不确定我是否非常了解您的问题,但您为什么不使用 ContentPresenter?它允许在更高级别移动图像的代码。

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