2

我开始研究 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 行报告“ Invalid attribute value ActiveRatio for property Property ”

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

非常感谢!!!

4

1 回答 1

1

To be honest I can't see anything wrong with the code you've posted. Perhaps an explanation of exactly what causes the error you are seeing might give you some clues you can use.

The registration of the Dependancy property is what is important here:-

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

This creates and registers an instance of a dependency property against the combination of the string "ActiveRatio" and the Type ActionButton. When Silverlight comes to put the following Xaml into action:-

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

it combines the type specified in the TargetType attribute of the style with the string in the setters Property attribute to find the dependancy property instance. * It can then use the type indicated by the dependency property to convert the string in the setters Value attribute. Finally it can call SetValue on the FrameworkElement on which the style is set passing the DependencyProperty found and the converted value.

Now return the * in the previous paragraph. Its at this point that the code has failed. It is failing to find a dependency property registration for the string "ActiveRatio" and the type ActionButton.

I can't tell you why its failing, your code clearly registers this name and the type in the style matches the type passed in the registration. I've even written small repro of your code and it works fine.

All I can suggest is that you try a complete Rebuild and then run the code.

Assuming what you have posted is fairly complete the only other suggestion I have is such a "clutching at straws" exercise I'm not even going to explain my reason. Try adding this to you ActionButton class:-

 public static ActionButton() { }
于 2009-11-07T19:47:22.880 回答