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);
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.
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.
<!--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"-->
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; }
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.
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.
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:
When I apply this style to an object, some properties are set, some are not:
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 -...
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.
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:
BugTest1.xaml.cs
BugGauge.cs
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.
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:
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.