Signum Framework Logo
"Open framework that encourages convention over configuration, using C# code,
not XML files, to model at the right level of abstraction and achieve deadlines.
...but also has a full Linq provider, and syncs the schema for you!"
Login
RSS

Search

»



Main
Index
Map
Videos
Download
Source code
Tutorials
Forum
FAQ



Image



PoweredBy

Introduction

Common static class defines the Attached Properties that, in conjunction with Entity Controls, simplifies building UI code of business applications.

Let's see what these properties are and why they are useful.

TypeContext attached property

As you already know, DataContext property is a property of type object defined in the FrameworkElement class. It's meant to be used for data binding scenarios and is the default Binding Source.

Unfortunately, the actual type of the value inside DataContext is not known until runtime, when a value is inserted, neither the full property path is known that goes from the original entity (root) to it. Having this information available will make setting-up our Entity Controls much easier.

Common.TypeContext attached property, in conjunction with Common.Route, adds these contexts to your controls for you. There are two types of TypeContext:

public class TypeContext
{
     public Type Type {...}
}

public class TypeSubContext : TypeContext { public TypeContext Parent {...} public PropertyInfo PropertyInfo {...} }

  • TypeContext: The root of your context, the original IdentifiableEntity Type. Usually defined explicitly.
  • TypeSubContext: Defines accessing a property over another TypeContext. The Type is then the PropertyType of this property. It's ment to be created by Common.Route property.

The following example defines the interface for ProjectDN deffined here:

<UserControl x:Class="Bugs.Windows.Controls.Project"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:m="clr-namespace:Signum.Windows;assembly=Signum.Windows"
    xmlns:d="clr-namespace:Bugs.Entities;assembly=Bugs.Entities"
    m:Common.TypeContect="d:ProjectDN" 
    MinWidth="300">
    <StackPanel>
        <m:ValueLine m:Common.Route="Name"/>
        <m:ValueLine m:Common.Route="IsInternal" LabelText="Is Internal"/>
    </StackPanel>
</UserControl>

Let's see how this Route mechanism works.

Route attached property

Route attached property tries to simplify common DataBindig when building the controls for your custom entities. It does many things when set:

  • Update TypeContext conveniently.
  • Set Type property when applied over any Entity Control (ValueLine, EntityLine, EntityCombo, EntityList or FileLine) sets the corresponding Type property.
  • Create the Binding arranging all the binding options correctly (Mode, NotifyOnValidationError, ValidatesOnExceptions...) using the corresponding Binding target property.
  • Find Implementation when applied over any control inheriting EntityBase (EntityLine/Combo/List) setting the current types in the ImplementedBy attribute on the server Schema and setting the Implementations property.
  • Update LabelText with the last part of the Route value, if not set explicitly.

So writing something like this.
  <StackPanel m:Common.TypeContext="d:MyEntityDN">
    <m:EntityLine m:Common.Route="MyProperty"/>
  </StackPanel>

Gets expanded to this pseudo-XAML:
  <StackPanel m:Common.TypeContext="d:MyEntityDN">
    <m:EntityLine 
       m:Common.Route="MyProperty" 
       m:Common.TypeContext="TypeSubContext MyProperty"
       EntityType="MyPropertyType"
       Entity="{Binding MyProperty, NotifyOnValidationError=true, ValidatesOnExceptions=true, ValidatesOnDataErrors=true}"
       Implementations="Server.FindImplementations(MyEntityDN, MyProperty)"
       LabelText="MyProperty"/>
   </StackPanel>

As you see, the Common.TypeContext/Common.Route infrastructure is a huge time-saver. Let's see what properties are set when Common.Route is applied over Entity Controls.

ControlType propertyBinding target propertyImplementations property
ValueLineValueTypeValue
EntityLineEntityTypeEntityImplementations
EntityListEntitiesType and EntityTypeEntities Implementations
EntityComboEntityTypeEntity Implementations
FileLineEntityTypeEntity
any other control DataContext

So you can use the same way of using m.Common.Route for binding almost any control to your entity

Finally, the expressions you could write using in Common.Route are based in Binging.Path expressions:

  • Single Property: m.Common.Route="propertyName"
  • Multiple Property: m.Common.Route="propertyName.propertyName2" The '.' operator is able to concatenate in sub-properties of a property.
  • Source Transversal: m.Common.Route="collection/propertyNameX" The '/' gets into the current element of a collection.

There's no support for specifying ownerType in this synthax because the type is 'statically' known using TypeContext. We haven't added [index] support yet.

IsReadOnly attached property

This attached property is inherited by all the sub tree, changing the behaviour of any Entity Control, disabling anything that can actually modify the entity. (Remove, Search and Create buttons, disable ComboBox, etc...)

You can see more information of when each button is displayed in Entity Controls.

IsLabelVisible attached property

Many EntityControls (ValueLine, EntityLine, FileLine and EntityCombo) have a label on the left side of it. This label is visible by default and simplifies layout for the very common scenario of label-control pairs. (you can write the whole pair in one line)

You can turn off the visibility of these labels just by doing m:Common.IsLabelVisible="false".

This property is Inherited so it affects the whole sub-tree.

LabelWidth attached property

This property lets you control the width available for these labels on the right side.

This property is Inherited so it affects the whole sub-tree.

CurrentWindow attached property

Some EntityControls need to know the current window (i.e. Creating). Usually they find out the current window by themselves but in complex DataTemplate you will have to tell them explicitly.

This property is Inherited so it affects the whole sub-tree.

Utility Methods

Commons static class also offers some useful methods:

//Walking up the tree looking for a windows, or a control with CurrentWindow property setted.
public static Window FindCurrentWindow(this FrameworkElement fe);

//Simplified way of knowing if a DependencyProperty has no local value (or binding). public static bool NotSet(this DependencyObject depObj, DependencyProperty prop);

//Returns the sequence of parents. public static IEnumerable<DependencyObject> Parents(this DependencyObject child);

//Convert true to Visibility.Visible, false to Visibility.Collapsed public static Visibility ToVisibility(this bool val);

//Returns true if val == Visibility.Visible public static bool FromVisibility(this Visibility val);

//Does a Breath-first search in a subtree, returning the first DependencyObject that satisfies the predicate public static DependencyObject FindChildrenBreadthFirst(DependencyObject parent, Predicate<DependencyObject> predicate)



Creative Commons License Signum Framework Site by Signum Software is licensed under a Creative Commons Attribution 3.0 License.
Powered by ScrewTurn Wiki version 3.0.5.600.