Как использовать свойства пользовательского элемента управления WPF в шаблоне XAML? - PullRequest
3 голосов
/ 07 июля 2010

Я создал пользовательский элемент управления, который предназначен для использования в качестве кнопки, но имеет свойства для указания точек для многоугольника (для рисования внутри кнопки) и двух цветов для градиента. Я объявил все свойства в коде, а затем написал шаблон в XAML, но, похоже, он не работает. Если я жестко закодирую значения в XAML, он будет работать нормально, но, похоже, ничего не произойдет, если я использую значения свойств через TemplateBinding. Любые идеи о том, как заставить это работать?

Вот мой XAML:

<Window x:Class="WPFTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" xmlns:my="clr-namespace:WPFTest">
    <StackPanel>
        <StackPanel.Resources>
            <Style TargetType="my:GradientButton">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type my:GradientButton}">
                            <Grid>
                                <Ellipse Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Stroke="{TemplateBinding Foreground}" VerticalAlignment="Top" HorizontalAlignment="Left">
                                    <Ellipse.Fill>
                                        <LinearGradientBrush>
                                            <GradientStop Color="{TemplateBinding GradientStart}" Offset="0"></GradientStop>
                                            <GradientStop Color="{TemplateBinding GradientEnd}" Offset="1"></GradientStop>
                                        </LinearGradientBrush>
                                    </Ellipse.Fill>
                                </Ellipse>
                                <Polygon Points="{TemplateBinding PlayPoints}" Fill="{TemplateBinding Foreground}" />
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </StackPanel.Resources>
        <my:GradientButton Content="Button" Height="50" x:Name="gradientButton1" Width="50" GradientStart="#CCCCCC" GradientEnd="#777777" />
    </StackPanel>
</Window>

А вот код для пользовательского элемента управления:

public class GradientButton : Button
    {
        internal static DependencyProperty GradientStartProperty;
        internal static DependencyProperty GradientEndProperty;
        internal static DependencyProperty PlayPointsProperty;

        static GradientButton()
        {
            GradientStartProperty = DependencyProperty.Register("GradientStart", typeof(Color), typeof(GradientButton));
            GradientEndProperty = DependencyProperty.Register("GradientEnd", typeof(Color), typeof(GradientButton));
            PlayPointsProperty = DependencyProperty.Register("PlayPoints", typeof(Point[]), typeof(GradientButton));
        }

        public Color GradientStart
        {
            get { return (Color)base.GetValue(GradientStartProperty); }
            set { SetValue(GradientStartProperty, value); }
        }

        public Color GradientEnd
        {
            get { return (Color)base.GetValue(GradientEndProperty); }
            set { SetValue(GradientEndProperty, value); }
        }

        public Point[] PlayPoints
        {
            get //hardcoded return at the moment to get it to work, but this will change later
            {
                System.Collections.Generic.List<Point> result = new System.Collections.Generic.List<Point>();

                double left = this.Width / 2.77;
                double top = this.Height / 4.17;
                double right = this.Width / 1.43;
                double middle = this.Height / 2.0;
                double bottom = this.Height / 1.32;

                result.Add(new Point(left, top));
                result.Add(new Point(right, middle));
                result.Add(new Point(left, bottom));

                return result.ToArray();
            }
            set { SetValue(PlayPointsProperty, value); }
        }
    }

Ответы [ 2 ]

3 голосов
/ 07 июля 2010

Попробуйте использовать это вместо своих цветовых привязок:

Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=GradientStart}"

TemplateBinding работает только в ограниченных ситуациях, когда объявления находятся в элементах визуального дерева ControlTemplate, что не относится к вашей LinearGradientBrush. Вы можете увидеть то же поведение и использовать то же исправление в Trigger Setters в ControlTemplate.

3 голосов
/ 07 июля 2010

Polygon.Points относится к типу PointCollection.Я не верю, что Point[] соответствует этому типу.Вам нужно будет либо изменить тип PlayPoints, либо использовать IValueConverter для изменения его типа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...