Attached properties - the basics
One of the coolest features in Avalon is the property subsystem. While it might seem difficult for some that Avalon has a property system built on top of the normal CLR properties, the power that this system gives you is incredible and is part of why a lot of scenarios in Avalon require less code than their counterparts in other systems.
One cool thing that the property system in Avalon allows is attached properties. The simplest way to explain an attached property is that it allows the place where the property is defined and the place where it is stored to be completely different classes that know nothing about each other. The only restriction is that the property value can only be stored on DependencyObject objects (which happens to be the base class for most Avalon things).
Why is this so cool? The best example is how DockPanel uses attached properties. When you add elements to a DockPanel, you need to tell the DockPanel on what side to Dock the elements. WinForms uses the Dock property on the Control class for this. But you then pay the tax of having the property on the Control, even though you are not always being docked. The property only makes sense to the docking code.
In Avalon the DockPanel defines an attached property (DockPanel.DockProperty) that tells the DockPanel where to dock a child element. You can set the property on the child element from code:
DockPanel.SetDock(element, Dock.Left);
Or from XAML:
<UIElement DockPanel.Dock=”Left” />
The DockPanel reads off the value and uses it during the layout. Because it is using attached properties, the UIElement and associated classes do not need to know about how DockPanel works, and there can be a multitude of properties used by various panels for layout without bloating UIElement with spurious properties.
Defining your own attached properties is easy - I have made a quick sample to show how to do this. The idea behind the sample is to make a panel called RadialPanel that arranges children in a radial pattern, and has an attached property Angle that shows where to place the children.
The first thing that we do is create a new class called RadialPanel (make sure it is public or the XAML cannot find it!). We then add an attached property to the class as such:
public static readonly DependencyProperty AngleProperty = DependencyProperty.RegisterAttached(
“Angle”,
typeof(double),
typeof(RadialPanel),
new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsParentArrange));
Here is some explanation about this blob of code (if you work with Avalon a while you end up writing stuff like this a lot):
We make the DependencyProperty public because other people need to reference it.
It is static because this object is only really describing the property, not storing it per instance.
We make it read only, because we don’t want people to overwrite it.
We define the type of the value stored (double) and the type of the owner (RadialPanel).
The metadata tells Avalon what the default value is, and it also says that changing the value of this property will invalidate arrange on the parent of the object that the value is set on. This is very handy, because we don’t need to write a handler for when the property changes.
After we write this code, we write some accessor methods. We need to do this or Avalon will not be able to change the values from XAML. These are just static methods that wrap the Avalon GetValue/SetValue methods:
public static double GetAngle(DependencyObject obj)
{
return (double)obj.GetValue(AngleProperty);
}
public static void SetAngle(DependencyObject obj, double value)
{
obj.SetValue(AngleProperty, value);
}
Now we can implement the measure and arrange code. The measure code is fairly straightforward - we just decide how big each child will be and measure the children like that:
protected override Size MeasureOverride(Size availableSize)
{
// find out the radius of the children (it is 1/3rd of the minor axis of the RadialPanel)
double childRadius = Math.Min(availableSize.Width, availableSize.Height) / 3.0;
// measure each of the children with this size
foreach (UIElement element in this.InternalChildren)
{
element.Measure(new Size(childRadius, childRadius));
}
// tell our layout parent that we used all of the space up
return availableSize;
}
And now we can write the arrange, which is simple as well. Notice that we grab the value of the attached property to figure out where to put the element:
protected override Size ArrangeOverride(Size finalSize)
{
// figure out the size for the children
double childRadius = Math.Min(finalSize.Width, finalSize.Height) / 3.0;
foreach (UIElement element in this.InternalChildren)
{
double angle = GetAngle(element);
// figure out where the child goes in cartesian space. We invert the
// Y value because screen space and normal mathematical cartesian space
// are reversed in the vertical.
Point childPoint = new Point(
Math.Cos(angle * Math.PI / 180.0) * childRadius,
-Math.Sin(angle * Math.PI / 180.0) * childRadius);
// offset to center of the panel
childPoint.X += finalSize.Width / 2;
childPoint.Y += finalSize.Height / 2;
// arrange so that the center of the child is at the point we calculated,
// and the child is of the calculated radius.
element.Arrange(new Rect(
childPoint.X - childRadius / 2.0,
childPoint.Y - childRadius / 2.0,
childRadius,
childRadius));
}
// we used up all of the space
return finalSize;
}
Now the panel is written we can test it out with some simple XAML:
<Window x:Class=”RadialPanelDemo.Window1″
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
xmlns:local=”clr-namespace:RadialPanelDemo”
Title=”RadialPanelDemo” Height=”300″ Width=”300″
>
<local:RadialPanel x:Name=”radialPanel”>
<Button Content=”Button One” local:RadialPanel.Angle=”30″ Opacity=”0.5″ />
<Button Content=”Button Two” local:RadialPanel.Angle=”90″ Opacity=”0.5″ />
<Button Content=”Button Three” local:RadialPanel.Angle=”120″ Opacity=”0.5″ />
<Button Content=”Button Four” local:RadialPanel.Angle=”250″ Opacity=”0.5″ />
</local:RadialPanel>
</Window>
We give some transparency to the buttons so that we can see them when they overlap each other. One last bit of fun is showing changes to the property value and showing how the layout updates automatically. In the InitializeComponent of the window, we add an event handler to the buttons:
// whenever one of the buttons is clicked, handle it in the same place
foreach (Button button in radialPanel.Children)
{
button.Click += new RoutedEventHandler(OnButtonClick);
}
And write the handler:
void OnButtonClick(object sender, RoutedEventArgs e)
{
// find out who was clicked
Button button = (Button)e.OriginalSource;
// increment angle by 15 degrees
RadialPanel.SetAngle(button, RadialPanel.GetAngle(button) + 15.0);
}
Now when we click the buttons, they each move 15 degrees around the circle!
This is just the beginning of what attached properties can do. I will try to blog about more advanced usage soon. Please let me know if there is a specific Avalon property system feature that you want an article about.
Update: I uploaded the code for this example.…more
Watch the Ultra porn clip now.3 September.
Enter here to access Fanta porrn site.
More information on Uninstaller and cleaner.
Absolute Megateen hot sex full Samples.
Comment by Korrine — October 24, 2007 @ 1:40 pm
I like this Malemaxx penis clip.
15 Minutes full version To Watch Any Causes of weight loss Sample 1 July.
Enter here for search results Erotic lactaphilia.
Enter FOR Iu porn video.
Comment by Noralie — November 7, 2007 @ 10:47 am
Brazilian escorts br full version Sample.
Straponall Gallery Index 1 Index 2 Index 3.
My naghty Lds young women movies.
6 December.Adult search results Tgp pissing 18 June.
full version Viacyn related downloads.
Comment by Studs — November 8, 2007 @ 4:50 pm
Pictures of teen hottest samples.
Click to see Comicss Full length sex Sample video Clips instantly.
Very hot Horse health products!.Enter to take a look at films.
watch Puke site full clip.Enter now for more.
Unlike most of The best bangbros models sites we make sure that our site have the best clips and video.
Comment by Clay — December 16, 2007 @ 6:56 pm
Send Us Your Hot The life of a slave pics films & films!.
Enter Effects of a low carb diet directory online.Click here to view.
Erica links film collection.
Comment by Buffy — December 28, 2007 @ 10:27 pm
Looking for kids-bedding.respect-ufa.ru? Find exactly what you want today.
Comment by Carman — January 23, 2008 @ 7:12 am
Reliable content on Actual price & Photos.
online purchase fan-merchandise.ecofinance.ru page Actual price & Photos.
balloonfetishvideos.obrokblog.com Features:View New Local Listings Now!.
herselfzri.sellerie-bourgoin.com product was added to our catalog on 11 May, 2006.
Comment by Brice — January 25, 2008 @ 7:56 am
double-penetrations.filereaction.com online Website.2 February, 2006.
Buy online homes.ticketplus.ru online and save time!.
Forums Computer best-sponsor.dotfreenet.com Forum.
Enter books.nuse.ru portal.1 April.
Comment by Lecea — January 26, 2008 @ 4:14 pm
Cheapest price when ordering hair-loss.damakzevki.net online.
Order sexy-pantyhose.raoulburnhard.com direct. Online Specials available: Save up to 8% off retail.
Looking for video.allbuynow.co.uk? Find exactly what you want today.
Add pussy-in.beststorecentral.com to basket!Find the Instant Price. Good, Free offer!.
Comment by Matty — January 27, 2008 @ 11:14 pm
you probably haven’t seen yet.
Comment by Janet — February 23, 2008 @ 12:01 pm