【问题标题】:Is template binding to a Geometry possible模板绑定到几何是否可能
【发布时间】:2012-03-06 20:20:58
【问题描述】:

我目前有一个自定义Button 控件,它通过ControlTemplate 类型的依赖属性在控件上显示DrawingImage 集。我一直试图将DrawingImage 移动到控制模板中并绑定到Geometry,但失败了。是否可以绑定到Geometry 对象?如果不是,为什么不,如果是,我错过了什么?

下面的截图显示了我在右侧的成功尝试和左侧的失败尝试。

绑定到 DrawingImage 的示例(有效) - generic.xaml:

<Style TargetType="{x:Type local:RoundButton3}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:RoundButton3}">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>

                    <Ellipse StrokeThickness="5" Stroke="Green"/>

                    <Viewbox Margin="10" Stretch="Uniform">
                        <ContentControl 
                            Template="{TemplateBinding ImageTemplate}" />
                    </Viewbox>

                    <TextBlock VerticalAlignment="Center" 
                               Grid.Column="1" 
                               Text="Round Button" Margin="5,0,0,0" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

public class RoundButton3 : Button
{
    static RoundButton3()
    {
        DefaultStyleKeyProperty.OverrideMetadata(
            typeof(RoundButton3), 
            new FrameworkPropertyMetadata(typeof(RoundButton3)));
    }

    public static readonly DependencyProperty ImageTemplateProperty =
        DependencyProperty.Register(
            "ImageTemplate", typeof (ControlTemplate), typeof (RoundButton3),
            new FrameworkPropertyMetadata(
                default(ControlTemplate),
                FrameworkPropertyMetadataOptions.AffectsRender |
                FrameworkPropertyMetadataOptions.AffectsMeasure));

    public ControlTemplate ImageTemplate
    {
        get { return (ControlTemplate)GetValue(ImageTemplateProperty); }
        set { SetValue(ImageTemplateProperty, value); }
    }
}

并像这样使用

    <Grid.Resources>
        <GeometryGroup x:Key="AddGeometry">
            <LineGeometry StartPoint="25,12" EndPoint="25,38" />
            <LineGeometry StartPoint="12,25" EndPoint="38,25" />
        </GeometryGroup>

        <ControlTemplate x:Key="RoundAddTemplate">
            <Image SnapsToDevicePixels="True">
                <Image.Source>
                    <DrawingImage>
                        <DrawingImage.Drawing>
                            <DrawingGroup>
                                <GeometryDrawing Pen="{StaticResource RoundButtonPen}" Geometry="{StaticResource AddGeometry}"/>
                            </DrawingGroup>
                        </DrawingImage.Drawing>
                    </DrawingImage>
                </Image.Source>
            </Image>
        </ControlTemplate>
    </Grid.Resources>

   <local:RoundButton3 
        Grid.Column="1"
        Content="RoundButton3" ImageTemplate="{StaticResource RoundAddTemplate}"/>

我尝试绑定到几何资源(不起作用) - generic.xaml:

<Style TargetType="{x:Type local:RoundButton2}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:RoundButton2}">
                    ...

                    <Viewbox Margin="10" Stretch="Uniform">
                        <Image>
                            <Image.Source>
                                <DrawingImage>
                                    <DrawingImage.Drawing>
                                        <DrawingGroup>
                                            <DrawingGroup.Children>
                                                <GeometryDrawing 
                                                  Pen="{StaticResource RoundButtonPen}" 
                                                  Geometry="{TemplateBinding Geometry}" />
                                            </DrawingGroup.Children>
                                        </DrawingGroup>
                                    </DrawingImage.Drawing>
                                </DrawingImage>
                            </Image.Source>
                        </Image>
                    </Viewbox>

                    ...
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

在哪里

public class RoundButton2 : Button
{
    static RoundButton2()
    {
        DefaultStyleKeyProperty.OverrideMetadata(
            typeof(RoundButton2), 
            new FrameworkPropertyMetadata(typeof(RoundButton2)));
    }

    #region Geometry

    public static readonly DependencyProperty GeometryProperty =
        DependencyProperty.Register(
            "Geometry", typeof (Geometry), typeof (RoundButton2),
            new FrameworkPropertyMetadata(
                default(Geometry),
                FrameworkPropertyMetadataOptions.AffectsRender | 
                FrameworkPropertyMetadataOptions.AffectsMeasure));

    public Geometry Geometry
    {
        get { return (Geometry)GetValue(GeometryProperty); }
        set { SetValue(GeometryProperty, value); }
    }

    #endregion
}

和使用一样

    <local:RoundButton2 
        Grid.Column="0"
        Geometry="{StaticResource AddGeometry}"
        Content="RoundButton2" />

使用前面定义的 AddGeometry 资源。

【问题讨论】:

    标签: wpf xaml custom-controls controltemplate


    【解决方案1】:

    如果您替换,您的代码应该可以工作

    <GeometryDrawing
        Geometry="{TemplateBinding Geometry}" />
    

    通过

    <GeometryDrawing
        Geometry="{Binding Geometry, RelativeSource={RelativeSource TemplatedParent}}" />
    

    请参阅this question 了解说明。

    【讨论】:

    • 谢谢,我尝试了除此之外的所有方法 :( 你知道为什么,因为我的印象是 TemplateBinding 等同于 RelativeSource={RelativeSource TemplatedParent}?好的,我会看看stackoverflow.com/questions/1131222/…,这解释了它。
    • here
    猜你喜欢
    • 1970-01-01
    • 2012-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    相关资源
    最近更新 更多