使用DependencyProperty和ControlTemplate的Silverlight

时间:2009-11-07 14:32:21

标签: c# silverlight xaml properties controltemplate

我开始研究Silverlight 3和Visual Studio 2008.我一直在尝试使用看起来像圆圈的按钮控件创建Windows边栏小工具(我有几个“圆形”png图像)。我想要的行为如下:当鼠标悬停在图像上时,它会变得更大。当我们点击它时,它就会下降。当我们离开按钮的图像时,它再次变为正常尺寸 因为我将有几个这样的控件我决定实现自定义控件:像一个按钮,但图像和没有内容文本。
我的问题是我无法在模板和样式中设置自定义属性。

我做错了什么?

我的teamplate控件有三个额外的属性:

namespace SilverlightGadgetDocked {  
    public class ActionButton : Button {  
        /// <summary>  
        /// Gets or sets the image source of the button.  
        /// </summary>  
        public String ImageSource {  
            get { return (String)GetValue(ImageSourceProperty); }  
            set { SetValue(ImageSourceProperty, value); }  
        }  
        /// <summary>  
        /// Gets or sets the ratio that is applied to the button's size  
        /// when the mouse control is over the control.  
        /// </summary>  
        public Double ActiveRatio {  
            get { return (Double)GetValue(ActiveRatioProperty); }  
            set { SetValue(ActiveRatioProperty, value); }  
        }

        /// <summary>
        /// Gets or sets the offset - the amount of pixels the button 
        /// is shifted when the the mouse control is over the control.
        /// </summary>
        public Double ActiveOffset {
            get { return (Double)GetValue(ActiveOffsetProperty); }
            set { SetValue(ActiveOffsetProperty, value); }
        }

        public static readonly DependencyProperty ImageSourceProperty =
            DependencyProperty.Register("ImageSource",
            typeof(String),
            typeof(ActionButton),
            new PropertyMetadata(String.Empty));

        public static readonly DependencyProperty ActiveRatioProperty =
            DependencyProperty.Register("ActiveRatio",
            typeof(Double),
            typeof(ActionButton),
            new PropertyMetadata(1.0));

        public static readonly DependencyProperty ActiveOffsetProperty =
            DependencyProperty.Register("ActiveOffset",
            typeof(Double),
            typeof(ActionButton),
            new PropertyMetadata(0));

        public ActionButton() {
            this.DefaultStyleKey = typeof(ActionButton);
        }
    }
}

带样式的XAML:

<UserControl x:Class="SilverlightGadgetDocked.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:SilverlightGadgetDocked="clr-namespace:SilverlightGadgetDocked" 
    Width="130" Height="150" SizeChanged="UserControl_SizeChanged"  MouseEnter="UserControl_MouseEnter" MouseLeave="UserControl_MouseLeave">
    <Canvas>
        <Canvas.Resources>
            <Style x:Name="ActionButtonStyle" TargetType="SilverlightGadgetDocked:ActionButton">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="SilverlightGadgetDocked:ActionButton">
                            <Grid>
                                <Image Source="{TemplateBinding ImageSource}"
                                    Width="{TemplateBinding Width}"
                                    Height="{TemplateBinding Height}"/>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            <Style x:Key="DockedActionButtonStyle" TargetType="SilverlightGadgetDocked:ActionButton"
                   BasedOn="{StaticResource ActionButtonStyle}">
                <Setter Property="Canvas.ZIndex" Value="2"/>
                <Setter Property="Canvas.Top" Value="10"/>
                <Setter Property="Width" Value="30"/>
                <Setter Property="Height" Value="30"/>
                <Setter Property="ActiveRatio" Value="1.15"/>
                <Setter Property="ActiveOffset" Value="5"/>
            </Style>
            <Style x:Key="InfoActionButtonStyle" TargetType="SilverlightGadgetDocked:ActionButton"
                   BasedOn="{StaticResource DockedActionButtonStyle}">
                   <Setter Property="ImageSource" Value="images/action_button_info.png"/>
            </Style>
            <Style x:Key="ReadActionButtonStyle" TargetType="SilverlightGadgetDocked:ActionButton"
                   BasedOn="{StaticResource DockedActionButtonStyle}">
                <Setter Property="ImageSource" Value="images/action_button_read.png"/>
            </Style>
            <Style x:Key="WriteActionButtonStyle" TargetType="SilverlightGadgetDocked:ActionButton"
                   BasedOn="{StaticResource DockedActionButtonStyle}">
                <Setter Property="ImageSource" Value="images/action_button_write.png"/>
            </Style>
        </Canvas.Resources>
        <StackPanel>
                <Image Source="images/background_docked.png" Stretch="None"/>
                <TextBlock Foreground="White" MaxWidth="130" HorizontalAlignment="Right" VerticalAlignment="Top" Padding="0,0,5,0" Text="Name" FontSize="13"/>
        </StackPanel>
        <SilverlightGadgetDocked:ActionButton Canvas.Left="15" Style="{StaticResource InfoActionButtonStyle}" MouseLeftButtonDown="imgActionInfo_MouseLeftButtonDown"/>
        <SilverlightGadgetDocked:ActionButton Canvas.Left="45" Style="{StaticResource ReadActionButtonStyle}" MouseLeftButtonDown="imgActionRead_MouseLeftButtonDown"/>
        <SilverlightGadgetDocked:ActionButton Canvas.Left="75" Style="{StaticResource WriteAtionButtonStyle}" MouseLeftButtonDown="imgActionWrite_MouseLeftButtonDown"/>
    </Canvas>
</UserControl>

Visual Studio在第27行报告“属性属性的无效属性值ActiveRatio”

<Setter Property="ActiveRatio" Value="1.15"/>

非常感谢!!!

1 个答案:

答案 0 :(得分:1)

说实话,我发现您发布的代码没有任何问题。也许对你所看到的错误的确切原因的解释可能会给你一些你可以使用的线索。

在这里注册Dependancy属性非常重要: -

    public static readonly DependencyProperty ActiveRatioProperty =
        DependencyProperty.Register("ActiveRatio",
        typeof(Double),
        typeof(ActionButton),
        new PropertyMetadata(1.0));

这将根据字符串“ActiveRatio”和Type ActionButton的组合创建并注册依赖项属性的实例。当Silverlight将以下Xaml付诸行动时: -

<Style x:Key="Stuff" TargetType="local:ActionButton">
  <Setter Property="ActiveRatio" Value="1.15" />
</Style>

它将样式的TargetType属性中指定的类型与setters Property属性中的字符串组合在一起,以查找dependancy属性实例。 *然后,它可以使用依赖项属性指示的类型来转换setters Value属性中的字符串。最后,它可以在设置了样式的SetValue上调用FrameworkElement,通过找到的DependencyProperty和转换后的值。

现在返回上一段中的*。此时代码失败了。它无法为字符串“ActiveRatio”和类型ActionButton找到依赖项属性注册。

我无法告诉你为什么它失败了,你的代码清楚地注册了这个名字,风格中的类型与注册中传递的类型相匹配。我甚至写了你的代码的小代表,它工作正常。

我只能建议您尝试完整的重建,然后运行代码。

假设你发布的内容相当完整,我所拥有的唯一其他建议是如此“抓着吸管”练习我甚至都不会解释我的理由。尝试将此添加到ActionButton类: -

 public static ActionButton() { }