Avalon's naming conventions

A long time ago, I promised to document the various naming patterns that Avalon uses.  I still haven't done that, but I did the next best thing and convinced Tyler Barton to write it during his recent internship, and so rather than make people wait until the next CTP of the Avalon SDK docs, I figured I would share that information now, and give people a chance to comment on them:

CLR wrappers around dependency properties

Static dependency properties end in the word “Property”.  The CLR wrappers around these dependency properties drop this suffix.

For example, Control defines:
public static readonly DependencyProperty BackgroundProperty;
   and
public Brush Background { get; set; }

CLR events wrapping routed events
Static routed event members end in the sting “Event”.  The CLR events associated with these routed events drop this suffix.

For example, Button defines:
public static readonly RoutedEvent ClickEvent;
  and
public event RoutedEventHandler Click;

Commands
We have two separate naming patterns for commands.  The first pattern is when you have a collection of commands, you create a class to contain those commands, eg:
    public static class MediaCommands {
        public static UICommand Play { get; }
        ….
    }

For that pattern, the class name and is in “Commands”, but the field/property does not contain “Commands”.

The second pattern is for when you just have one or two commands and don’t want to create whole class to contain them.  In this case, the field/property holding the command should end in “Command”, for example:
    public class DocumentViewer : Control, … {
        public static UICommand ZoomIncreaseCommand { get; }
    }

The above examples used a read-only property, but using a read-only fields is also acceptable:

public static readonly ZoomIncreaseCommand = …;

Runtime Serialization Checks
Properties that require runtime checks for serialization may be accompanied by ShouldSerialize<Foo> methods.  These methods are called at runtime to determine whether or not serialization should proceed.

For example, BooleanAnimation defines this for the From property:
        private bool ShouldSerializeFrom();

Markup Extensions
Markup Extension classes must end in the word Extension.  The Extension suffix is dropped when the markup extension is used in xaml. 

Eg, the class TypeExtension can be used in markup:
<SomeClass SomeProperty=”{x:Type Foo}”/>
Or
<SomeClass>
    <SomeClass.SomeProperty>
        <x:TypeExtension TypeName=”Foo”/>
    </SomeClass.SomeProperty>
</SomeClass>

Attached Properties
Attached properties are wrapped with CLR assessors defined in the parent class.

For example, DockPanel defines:

public static Dock GetDock(UIElement element);
  And
public static void SetDock(UIElement element, Dock dock);
 And
public static readonly DependencyProperty DockProperty;

For accessing the foreground attached property.

Attached Events
Attached events follow the same pattern.  The parent class defines a static Add[EventName]EventHandler function for each attached event. 

The idea is that child objects will provide values or delegates in xaml for attached properties and events and the parser will choose the correct method belonging to the parent.

For example, the Mouse class defines:
public static readonly RoutedEvent QueryCursorEvent;
 And
public static void AddQueryCursorHandler(
    DependencyObject element, QueryCursorEventHandler handler);
 And
public static void RemoveQueryCursorHandler(
    DependencyObject element, QueryCursorEventHandler handler);

Reflection Example

This code segment lists all the CLR properties of the Control class that are backed with DependencyProperties.

Type controlType = typeof(System.Windows.Controls.Control);

PropertyInfo[] properties = controlType.GetProperties();

for (int i = 0; i < properties.Length; i++)
{
String dependencyPropertyFieldName =
properties[i].Name + "Property";

if (controlType.GetField(dependencyPropertyFieldName, BindingFlags.Static) != null)
      {
       System.Console.WriteLine(
                 properties[i].Name +
" is backed with a dependency property");
}               
}

-Nick
---
This posting is provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified at https://www.microsoft.com/info/cpyright.htm.