Search code examples
silverlightstylesvisualstatemanagervisualstates

Can't reuse style in silverlight 5


I create a custom image button and add some style. everything works fine. But when i try to reuse it in other buttons, it didn't work very well. only 1 button will follow the style, others are always blank.

i didn't got any error in runtime. Please help!!

Thx

Here are the code:

Button:

    public class ImageTextButton : Button
{
    public DependencyProperty TextProperty { get; set; }
    public DependencyProperty ImageProperty { get; set; }

    public ImageTextButton()
    {
        TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(ImageTextButton), null);
        ImageProperty = DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(ImageTextButton), null);
    }

    public ImageSource ImageSource
    {
        get { return (ImageSource)GetValue(ImageProperty); }
        set { SetValue(ImageProperty, value); }
    }

    public string Text { get; set; }
}

xaml:

<Controls:ImageTextButton HorizontalAlignment="Left" Command="{Binding SendCustomerChanges}" Style="{StaticResource ImageTextButton}" IsEnabled="{Binding Path=DetailsInformation.IsAllowSave}"
                             Text="{Binding Path=CustomerResources.Button_CloseDetailedView, Source={StaticResource ResourceWrapper}}" ImageSource="{Binding Path=SaveIcon, Source={StaticResource ApplicationIcons}}" />

style:

    <Style TargetType="Controls:ImageTextButton" x:Key="ImageTextButton" >
    <Setter Property="FontFamily" Value="Arial"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Controls:ImageTextButton">
                <Grid>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommomStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ColorAnimation Duration="0" To="LightGray" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="rectangle"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled" >
                                <Storyboard>
                                    <DoubleAnimation Duration="0" Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity" To="1"/>
                                    <ColorAnimation Duration="0" To="#AAAAAA" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="textBlock" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Rectangle x:Name="rectangle" Fill="#E0E9F1"  StrokeThickness="1" Stroke="#728DA3"/>
                    <Rectangle x:Name="DisabledVisualElement" Fill="#F5F5F5" IsHitTestVisible="false" StrokeThickness="1" Stroke="#D3D3D3" Opacity="0" />
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition></ColumnDefinition>
                            <ColumnDefinition></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Image Grid.Column="0" Width="12" Height="12" Margin="2,0,2,0" Source="{TemplateBinding ImageSource}">
                        </Image>
                        <TextBlock Grid.Column="1" x:Name="textBlock" Margin="2,3,4,0" Text="{TemplateBinding Text}" />
                    </Grid>
                    <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5,3,5,3"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Solution

  • There are a few things you need to change/fix.

    1. Your Text Depenency Property is badly formed. You must define a getter and setter for the DP (as you have done with the ImageSourceProperty).

    2. Your ImageSource Dependency Property needs some attention too... The DP should be named ImageSourceProperty ... Dependency Properties must follow the pattern described here if they are to work under all conditions. Especially so when you are setting them from XAML

    3. You need a default style key for your new class so that your style is actually applied

    4. Your dependency properties should be registered in a static constructor (or as a field initializer. Not in the instance constructor.

      public class ImageTextButton : Button
      {
          public ImageTextButton()
          {
              DefaultStyleKey = typeof(ImageTextButton);
          }
      
          static ImageTextButton()
          {
              TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(ImageTextButton), new PropertyMetadata(null));
              ImageSourceProperty = DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(ImageTextButton), new PropertyMetadata(null));
          }
      
          public string Text
          {
              get { return (string)GetValue(TextProperty); }
              set { SetValue(TextProperty, value); }
          }
      
          // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
          public static readonly DependencyProperty TextProperty;
      
      
      
          public ImageSource ImageSource
          {
              get { return (ImageSource)GetValue(ImageSourceProperty); }
              set { SetValue(ImageSourceProperty, value); }
          }
      
          // Using a DependencyProperty as the backing store for ImageSource.  This enables animation, styling, binding, etc...
          public static readonly DependencyProperty ImageSourceProperty;
      
      
      }