Powered by MSDN

US - English
NEW! Silverlight 5 is available Learn More

Point, Size and Enum not honored in a Style RSS

4 replies

Last post Oct 28, 2008 03:04 PM by andulvar

(0)
  • andulvar

    andulvar

    Member

    181 Points

    129 Posts

    Point, Size and Enum not honored in a Style

    Oct 23, 2008 04:24 PM | LINK

    I have a style that look like this:

    <Style TargetType="dh:GaugeScale" x:Key="EmptyScale">
    <Setter Property="TickRadius" Value="40 40"/>
    <Setter Property="OuterRadius" Value="49 49"/>
    <Setter Property="MajorTickSpacing" Value="10"/>
    <Setter Property="MinorTickSpacing" Value="5"/>
    <Setter Property="AngleRange" Value="90 180"/>
    <Setter Property="ValueRange" Value="100 0"/>
    <Setter Property="Viewport" Value="-50 -10 60 60"/>
    <Setter Property="NominalSize" Value="400 400"/>
    <Setter Property="TextOrientation" Value="BaseIn"/>
    <Setter Property="TextPosition" Value="Inside"/>
    <Setter Property="TickHide" Value="Neither"/>
    <Setter Property="Closure" Value="Wedge"/>
    </Style>

    When I apply this style to an object, some properties are set, some are not:

    • Point TickRadius - Not set
    • Point OuterRadius - Not set
    • double MajorTickSpacing - Set
    • double MinorTickSpacing - Set
    • Point AngleRange - Not Set
    • Point ValueRange - Not Set
    • Rect Viewport - Set
    • Size NominalSize - Not Set
    • Enum TextOrientation - Not Set
    • Enum TextPosition - Not Set
    • Enum TickHide - Not Set
    • Enum Closure - Not Set

    Notice the weird thing here:  the double and Rect properties are set correctly.

    If I put all of these directly into the object definition, they are all set properly.


  • Yi-Lun Luo - MSFT

    Yi-Lun Luo -...

    All-Star

    25149 Points

    2759 Posts

    Microsoft

    Re: Point, Size and Enum not honored in a Style

    Oct 27, 2008 07:11 AM | LINK

    Hello, can you post some code? I tried this and it worked fine:

    public partial class SilverlightControl1 : UserControl

    {

    public Size MySize

    {

    get { return (Size)GetValue(MySizeProperty); }set { SetValue(MySizeProperty, value); }

    }

    // Using a DependencyProperty as the backing store for MySizeProperty. This enables animation, styling, binding, etc...

    public static readonly DependencyProperty MySizeProperty =DependencyProperty.Register("MySize", typeof(Size), typeof(SilverlightControl1), null);

     

    public Point MyPoint

    {

    get { return (Point)GetValue(MyPointProperty); }

    set { SetValue(MyPointProperty, value); }

    }

    // Using a DependencyProperty as the backing store for MyPointProperty. This enables animation, styling, binding, etc...

    public static readonly DependencyProperty MyPointProperty =DependencyProperty.Register("MyPoint", typeof(Point), typeof(SilverlightControl1), null);

     

    public SilverlightControl1()

    {

    InitializeComponent();

    }

    }

     

    <UserControl.Resources>

    <Style x:Key="style1" TargetType="StackPanel">

    <Setter Property="Orientation" Value="Horizontal"/>

    </Style>

    <Style x:Key="style2" TargetType="local:SilverlightControl1">

    <Setter Property="MyPoint" Value="100,100"/>

    <Setter Property="MySize" Value="20,15"/>

    </Style>

    </UserControl.Resources>

     

    <Grid x:Name="LayoutRoot" Background="White">

    <StackPanel Style="{StaticResource style1}">

    <Button Content="b1" Click="Button_Click"/>

    <Button Content="b2"/>

    <local:SilverlightControl1 x:Name="sc" Style="{StaticResource style2}"/>

    </StackPanel>

    </Grid>

     

    private void Button_Click(object sender, RoutedEventArgs e)

    {

    Point p = sc.MyPoint;

    Size s = sc.MySize;

    }

     

    The result I got is: The two Buttons are aligned horizontally. When I click the first Button, p is 100,100 and s is 20,15.

    Maybe your properties are not DependencyProperties? Setter is only valid for DependencyProperties.

    shanaolanxing - I'll transfer to the Windows Azure team, and will have limited time to participate in the Silverlight forum. Apologize if I don't answer your questions in time.
  • andulvar

    andulvar

    Member

    181 Points

    129 Posts

    Re: Point, Size and Enum not honored in a Style

    Oct 27, 2008 09:17 PM | LINK

    Hi.  I've tried to narrow this one down to a small test, and here is what I have.  Three files:

    • BugTest1.xaml - the main page
    • BugTest1.xaml.cs
    • BugGauge.cs - definitions for two classes. There are comments in  OnApplyTemplate and BugScale_Loaded to show where to put a breakpoint to see that some of the properties are set and some not.  Notice that OnApplyTemplate never even gets called.

    BugTest1.xaml:

     

    <UserControl x:Class="SilverlightTest.BugTest1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:dh="clr-namespace:DHControls;assembly=DHControls"
    >

    <UserControl.Resources>

    <Style TargetType="dh:BugScale" x:Key="LittleGauge">
    <Setter Property="TickRadius" Value="20,20"/>
    <Setter Property="OuterRadius" Value="40,40"/>
    <Setter Property="MajorTickSpacing" Value="25"/>
    <Setter Property="AngleRange" Value="-30 210"/>
    <Setter Property="ValueRange" Value="100 0"/>
    <Setter Property="Viewport" Value="-40,-40,80,80"/>
    <Setter Property="NominalSize" Value="100 100"/>
    <Setter Property="TextOrientation" Value="BaseIn"/>
    <Setter Property="TextPosition" Value="Inside"/>
    <Setter Property="TickHide" Value="Neither"/>
    <Setter Property="Closure" Value="Circle"/>
    </Style>

    <!--You can add these lines to the dh:BugScale definition below and remove the
    Style line from it to see the difference that style vs inline definition
    makes.-->
    <!--TickRadius="20,20"
    OuterRadius="40,40"
    MajorTickSpacing="25"
    AngleRange="-30,210"
    ValueRange="100,0"
    Viewport="-40,-40,80,80"
    Background="Transparent"
    NominalSize="100,100"
    TextOrientation="BaseIn"
    TextPosition="Inside"
    TickHide="Neither"
    Closure="Circle"-->


    <Style TargetType="dh:BugGauge" x:Key="InsertGauge">
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="dh:BugGauge">
    <dh:BugScale
    Style="{StaticResource LittleGauge}"
    DataContext="{TemplateBinding Value}"
    Position="{Binding}"
    Width="{TemplateBinding Width}"
    Height="{TemplateBinding Height}"
    >
    </dh:BugScale>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>

    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="Gray" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
    <Grid.RowDefinitions>
    <RowDefinition MinHeight="50" Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
    <ColumnDefinition MinWidth="50" Width="*"/>
    </Grid.ColumnDefinitions>
    <dh:BugGauge VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Style="{StaticResource InsertGauge}" Grid.Row="5" PointName="DataPid:PID1.Pv"/>
    </Grid>
    </UserControl>

    BugTest1.xaml.cs

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;

    namespace SilverlightTest
    {
    public partial class BugTest1 : UserControl
    {
    public BugTest1()
    {
    InitializeComponent();
    }
    }
    }

      BugGauge.cs

      

    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;

    namespace DHControls
    {
    public partial class BugScale : ContentControl
    {
    Rect m_Coord;

    public enum ETextOrientation { Horizontal, BaseIn, BaseOut, LeftIn, LeftOut }
    public enum ETextPosition { Inside, Outside }
    public enum ETickHide { First, Last, Both, Neither }
    public enum EClosure { Circle, Chord, Wedge }

    public BugScale()
    {
    DefaultStyleKey = typeof(BugScale);
    Loaded += new RoutedEventHandler(BugScale_Loaded);

    ValueRange = new Point(0, 100);
    AngleRange = new Point(0, 360);
    m_Coord = new Rect(-50, -50, 100, 100);
    OuterRadius = new Point(40, 40);
    TickRadius = new Point(40, 40);
    TextOrientation = ETextOrientation.Horizontal;
    TextPosition = ETextPosition.Outside;
    NominalSize = new Size(100, 100);
    TickHide = ETickHide.Neither;
    Closure = EClosure.Chord;
    }

    public override void OnApplyTemplate()
    {
    // Break here to examine values
    base.OnApplyTemplate();
    }

    void BugScale_Loaded(object sender, RoutedEventArgs e)
    {
    // Break here to examine values
    }

    #region Properties
    public static readonly DependencyProperty PositionProperty =
    DependencyProperty.Register(
    "Position", typeof(double), typeof(BugScale),
    new PropertyMetadata(0.0, new PropertyChangedCallback(OnPositionChanged)));
    public double Position
    {
    get { return (double)GetValue(PositionProperty); }
    set { SetValue(PositionProperty, value); }
    }

    public static readonly DependencyProperty MajorTickSpacingProperty =
    DependencyProperty.Register(
    "MajorTickSpacing", typeof(double), typeof(BugScale), null);
    public double MajorTickSpacing
    {
    get { return (double)GetValue(MajorTickSpacingProperty); }
    set { SetValue(MajorTickSpacingProperty, value); }
    }

    public static readonly DependencyProperty MinorTickSpacingProperty =
    DependencyProperty.Register(
    "MinorTickSpacing", typeof(double), typeof(BugScale), null);
    public double MinorTickSpacing
    {
    get { return (double)GetValue(MinorTickSpacingProperty); }
    set { SetValue(MinorTickSpacingProperty, value); }
    }

    public static readonly DependencyProperty FaceBorderThicknessProperty =
    DependencyProperty.Register(
    "FaceBorderThickness", typeof(double), typeof(BugScale), null);
    public double FaceBorderThickness
    {
    get { return (double)GetValue(FaceBorderThicknessProperty); }
    set { SetValue(FaceBorderThicknessProperty, value); }
    }

    public static readonly DependencyProperty ValueRangeProperty =
    DependencyProperty.Register(
    "ValueRange", typeof(Point), typeof(BugScale), null);
    public Point ValueRange
    {
    get { return (Point)GetValue(ValueRangeProperty); }
    set { SetValue(ValueRangeProperty, value); }
    }

    // sweep is counter-clockwise, so we have to ensure that end
    // angle is higher than start angle.

    public static readonly DependencyProperty AngleRangeProperty =
    DependencyProperty.Register(
    "AngleRange", typeof(Point), typeof(BugScale), null);
    public Point AngleRange
    {
    get { return (Point)GetValue(AngleRangeProperty); }
    set
    {
    while (value.Y < value.X) value.Y += 360;
    SetValue(AngleRangeProperty, value);
    }
    }

    public static readonly DependencyProperty OuterRadiusProperty =
    DependencyProperty.Register(
    "OuterRadius", typeof(Point), typeof(BugScale), null);
    public Point OuterRadius
    {
    get { return (Point)GetValue(OuterRadiusProperty); }
    set { SetValue(OuterRadiusProperty, value); }
    }

    public static readonly DependencyProperty TickRadiusProperty =
    DependencyProperty.Register(
    "TickRadius", typeof(Point), typeof(BugScale), null);
    public Point TickRadius
    {
    get { return (Point)GetValue(TickRadiusProperty); }
    set { SetValue(TickRadiusProperty, value); }
    }

    public static readonly DependencyProperty ViewportProperty =
    DependencyProperty.Register(
    "Viewport", typeof(Rect), typeof(BugScale), null);
    public Rect Viewport
    {
    get { return (Rect)GetValue(ViewportProperty); }
    set
    {
    Rect r = (Rect)value; SetValue(ViewportProperty, value);
    m_Coord = r;
    }
    }

    public static readonly DependencyProperty NominalSizeProperty =
    DependencyProperty.Register(
    "NominalSize", typeof(Size), typeof(BugScale), null);
    public Size NominalSize
    {
    get { return (Size)GetValue(NominalSizeProperty); }
    set { SetValue(NominalSizeProperty, value); }
    }

    public static readonly DependencyProperty TextOrientationProperty =
    DependencyProperty.Register(
    "TextOrientation", typeof(ETextOrientation), typeof(BugScale), null);
    public ETextOrientation TextOrientation
    {
    get { return (ETextOrientation)GetValue(TextOrientationProperty); }
    set { SetValue(TextOrientationProperty, value); }
    }

    public static readonly DependencyProperty TextPositionProperty =
    DependencyProperty.Register(
    "TextPosition", typeof(ETextPosition), typeof(BugScale), null);
    public ETextPosition TextPosition
    {
    get { return (ETextPosition)GetValue(TextPositionProperty); }
    set { SetValue(TextPositionProperty, value); }
    }

    public static readonly DependencyProperty TickHideProperty =
    DependencyProperty.Register(
    "TickHide", typeof(ETickHide), typeof(BugScale), null);
    public ETickHide TickHide
    {
    get { return (ETickHide)GetValue(TickHideProperty); }
    set { SetValue(TickHideProperty, value); }
    }

    public static readonly DependencyProperty ClosureProperty =
    DependencyProperty.Register(
    "Closure", typeof(EClosure), typeof(BugScale), null);
    public EClosure Closure
    {
    get { return (EClosure)GetValue(ClosureProperty); }
    set { SetValue(ClosureProperty, value); }
    }

    public static void OnPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
    BugScale b = (BugScale)d;
    b.Position = (double)e.NewValue;
    }
    #endregion
    }

    public partial class BugGauge : ContentControl
    {
    private double _Value;

    public BugGauge()
    {
    DefaultStyleKey = typeof(BugGauge);
    }

    private string _PointName;

    public static readonly DependencyProperty PointNameProperty =
    DependencyProperty.Register(
    "PointName", typeof(string), typeof(BugGauge),
    new PropertyMetadata(null, new PropertyChangedCallback(OnPointNameChanged)));

    public static readonly DependencyProperty ValueProperty =
    DependencyProperty.Register(
    "Value", typeof(double), typeof(BugGauge),
    new PropertyMetadata(0.0, new PropertyChangedCallback(OnValueChanged)));

    public static readonly DependencyProperty ValueStringProperty =
    DependencyProperty.Register("ValueString", typeof(string), typeof(BugGauge), null);
    public static readonly DependencyProperty ValueIntProperty =
    DependencyProperty.Register("ValueInt", typeof(Int32), typeof(BugGauge), null);

    public string PointName
    {
    get { return (string)GetValue(PointNameProperty); }
    set
    {
    _PointName = value;
    SetValue(PointNameProperty, value);
    }
    }

    public double Value
    {
    get { return (Double)GetValue(ValueProperty); }
    set
    {
    SetValue(ValueProperty, value);
    double oldval = _Value;
    _Value = value;
    ValueString = value.ToString();
    ValueInt = (Int32)value;
    }
    }

    public string ValueString
    {
    get { return (string)GetValue(ValueStringProperty); }
    set { SetValue(ValueStringProperty, value); }
    }

    public Int32 ValueInt
    {
    get { return (Int32)GetValue(ValueIntProperty); }
    set { SetValue(ValueIntProperty, value); }
    }

    public static void OnPointNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
    BugGauge b = (BugGauge)d;
    b.PointName = (string)e.NewValue;
    }

    public static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
    }
    }
    }
     
  • Yi-Lun Luo - MSFT

    Yi-Lun Luo -...

    All-Star

    25149 Points

    2759 Posts

    Microsoft

    Re: Point, Size and Enum not honored in a Style

    Oct 28, 2008 09:26 AM | LINK

     

    For the problem about OnApplyTemplate. Do you have a template for the Controls? You need a default template in themes\generic.xaml, or at least define a template in your ButTest.xaml. Else OnApplyTemplate will never be called.

    Another problem is: Why do you set values for those properties in BugScale's constructor? This will override the values you set in XAML. As soon as I remove those value settings, your code works fine for me. I added a break point in OnApplyTemplate and Loaded. In both places, I saw the values set in XAML. To set default values for a DependencyProperty, you do that when you register the property. I see you already did this for some properties:

    public static readonly DependencyProperty PositionProperty =

    DependencyProperty.Register(

    "Position", typeof(double), typeof(BugScale),

    new PropertyMetadata(0.0, new PropertyChangedCallback(OnPositionChanged)));

     

    Just do the same for any other properties that you want to give a default value. Don't set the values in the constructor.

    shanaolanxing - I'll transfer to the Windows Azure team, and will have limited time to participate in the Silverlight forum. Apologize if I don't answer your questions in time.
  • andulvar

    andulvar

    Member

    181 Points

    129 Posts

    Re: Re: Point, Size and Enum not honored in a Style

    Oct 28, 2008 03:04 PM | LINK

    Thank you.  That worked.

    I think we desperately need a Control lifecycle document.  My confusion exists because:

    • Style properties are applied before the constructor
    • In-line properties are applied after the constructor
    • Template is applied after the constructor
    • OnApplyTemplate only gets called if a default template exists

    We really need the whole lifecycle clarified.  There are many postings in these forums where people simply cannot figure out the order of construction, and cannot find a point in the construction of the object where they can rely on the properties to have been initialized.