Возможно ли связывание шаблона с геометрией - PullRequest
2 голосов
/ 07 марта 2012

В настоящее время у меня есть пользовательский элемент управления Button, который отображает DrawingImage, установленный для элемента управления через свойство зависимости типа ControlTemplate. Я пытался переместить DrawingImage в шаблон управления и привязать его к Geometry, но потерпел неудачу. Можно ли привязать объект Geometry? Если нет, то почему, а если нет, то чего мне не хватает?

На скриншоте ниже показана моя успешная попытка справа и неудачная попытка слева.

The problem

Пример привязки к 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, определенного ранее.

1 Ответ

5 голосов
/ 07 марта 2012

Ваш код должен работать, если вы замените

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

от

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

См. этот вопрос для объяснения.

...