代码之家  ›  专栏  ›  技术社区  ›  Sonny Boy

如何在XAML模板中使用WPF自定义控件属性?

  •  3
  • Sonny Boy  · 技术社区  · 15 年前

    我已经创建了一个自定义控件,它打算用作按钮,但具有指定多边形点(将在按钮内绘制)和两种渐变颜色的属性。我已经声明了代码中的所有属性,然后在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 回复  |  直到 15 年前
        1
  •  3
  •   Stephan    15 年前

    Polygon.Points 属于类型 PointCollection . 我不相信 Point[] 适合那种类型。您需要更改 PlayPoints 或者使用ivalueConverter进行类型更改。

        2
  •  3
  •   John Bowen    15 年前

    尝试将其用于颜色绑定:

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

    TemplateBinding仅在声明位于ControlTemplate的可视树元素中的有限情况下工作,而LinearGradientBrush则不是这种情况。您可以在ControlTemplate中的触发器setter中看到相同的行为,并使用相同的修复方法。

    推荐文章