Showing posts with label Code Experiences. Show all posts
Showing posts with label Code Experiences. Show all posts

Tuesday, April 28, 2015

Crosstalk between modules : Query providers and Event Managers

*Pub-sub mechanism in an LOB application  
 //Account class  
 AccountModule.AccountSearchVM  
 {  
 //property  
      public AccountViewModel SelectedAccount  
      {  
           get...  
           set  
           {  
                //other code here  
                //raise the event when account is selected  
                SelectedAccountEventArgs accountSelectedEvent = new SelectedAccountEventArgs();  
                EventManager.Current.PublishEvent<SelectedAccountEventArgs>(this, accountSelectedEvent);  
           }  
      }  
 }  
 //Positions class (show positions in right pane for selected account in the left pane [in AccountModule]  
 PositionsModule.PositionsVM  
 {  
      //ctor  
      PositionsVM()  
      {  
           ApplicationContext.Current.SubscribeToEvent<SelectedAccountEventArgs>(this, SelectedAccountChanged);  
           //Do something with SelectedAccountChanged method then, make use of SelectedAccountEventArgs  
      }  
 }  
--------------------------------------------------------
//QueryProviders  
 //This code is in Framework module  
 public void RegisterQueryProvider<QueryType>(QueryType query) where QueryType : IQueryProvider  
 {  
      Type type = typeof(QueryType);  
      //QueryManager is a singleton class which manages a dictionary of Dictionary<Type, IQueryProvider>  
      //instance is then added  
      //internal bool AddQuery<QueryType>(QueryType query) where QueryType : IQueryProvider  
   /* {  
           bool ret = false;  
           Type type = typeof(QueryType);  
           if (!m_queries.ContainsKey(type))  
           {  
                m_queries.Add(type, query);  
                ret = true;  
           }  
           return ret;  
      } */  
      if (!QueryManager.Current.AddQuery<QueryType>(query))  
      {  
           throw new Exception("Query is already registered!!.");  
      }  
 }  
 //inside Plugin initialze method, pass the instance of the view model  
 apphost.RegisterQueryProvider<ISelectedAccountQuery>(m_viewModel);  

Tuesday, February 17, 2015

Visitor pattern


Code:
class MutualFundOrderProvider
{
 private Dictionary<string,string> GetKeyValues(MutualFundOrderInfo info)
 {
  ...
 }
}

class GICOrderProvider
{
 private Dictionary<string,string> GetKeyValues(GICOrderInfo info)
 {
  ...
 }
}

class EquityOrderProvider
{
 private Dictionary<string,string> GetKeyValues(EquityOrderInfo info)
 {
  ...
 }
}

//visitor approach
//Create interface
interface IKeyValueComputer
{
 Dictionary<string,string> GetKeyValues(EquityOrderInfo info);
 Dictionary<string,string> GetKeyValues(GICOrderInfo info);
 Dictionary<string,string> GetKeyValues(MutualFundOrderInfo info)
}

//implementation
class KeyValueComputer:IKeyValueComputer
{
 //all implementations...
}

//another interface
interface IComputeKeyValues
{
 Dictionary<string,string> ComputeKeyValues(IKeyValueComputer keyvalcomp)
}

class EquityOrderInfo: IComputeKeyValues
{
 public Dictionary<string,string> ComputeKeyValues(IKeyValueComputer keyvalcomp)
 {
  return keyvalcomp.GetKeyValues(this);
 }
}

//MutualFundOrderProvider
class MutualFundOrderProvider
{
 public void Translate(MutualFundOrderInfo info)
 {
  IKeyValueComputer keyvalcomp=new KeyValueComputer();
  info.ComputeKeyValues(keyvalcomp);
 }
}

Sunday, February 15, 2015

Thursday, January 15, 2015

Client side threading in WPF (without Dispatcher)

Create a TaskItem class with 4 props:
1. Task name (string)
2. Action (Action)
3. int Priority
4. State (object)

Then create a static TaskProcessor class:
* has a dictionary of TaskItems as value and string as key
* static 'Current' property like this.

private TaskProcessor _current;  
 private int _threadID;  
 public static TaskProcessor Current  
 {  
   get  
   {  
      if (_current == null)  
      {  
        //lock to make thread safe  
        lock (typeof(TaskProcessor))  
        {  
           //create a new instance  
           _current = new TaskProcessor();  
           _threadID = Thread.CurrentThread.ManagedThreadId;  
        }  
      }
      return _current;  
   }  

Create a method in TaskProcessor class like this:

public void AddTaskInQueue(string taskName, Action<object> action, object state, int priority)  
 {  
   lock (this)  
   {  
      TaskItem ti = new TaskItem(this) { TaskName = taskName, Action = action, State = state, Priority = priority };  
      TaskItem currentTask = null;  
      if (_tasks.TryGetValue(taskName, out currentTask))  
      {  
        _tasks[taskName] = ti;  
      }  
      else  
      {  
        _tasks.Add(taskName, ti);  
      }  
      // Cancel the previous task.  
      if (currentTask != null)  
      {  
        //not in scope of this post
        currentTask.CancelTask();  
      }  
      // Identify and Cancel all other lower or equal priority tasks.  
      // Priority = 0 tasks are independent tasks  
      if (priority != 0)  
      {  
        var lowPriorityTasks = (from task in m_queue  
                       where task.Value.Priority > priority && task.Value.TaskName != taskName  
                       select task);  
        foreach (KeyValuePair<string, TaskItem> task in lowPriorityTasks)  
        {  
           task.Value.CancelTask();  
        }  
      }  
      ti.StartTheTask();  
   }  
 }  


Usage in code (upto what we have done till now) will be like this:

TaskProcessor.Current.AddTaskInQueue("SomeTaskName", action =>  
       {  
         //make call to svc to get data  
         ServiceResponse results = GetDataFromService();  
         //update UI after we get the results..  
         //this is covered later in this blog  
       }, null, 0);  



TaskItem class code:

private TaskProcessor _taskprocessor;  
     private SynchronizationContext _synchronizer;  

public TaskItem(TaskProcessor taskprocessor)
        {
            _taskprocessor = taskprocessor;
            _synchronizer= new TaskSynchronizationContext(SynchronizationContext.Current);

        }

     public void StartTheTask()  
     {  
       ThreadPool.QueueUserWorkItem(state =>  
       {  
         TaskItem ti = (TaskItem)state;  
         try  
         {  
           ti._taskprocessor.StartTask(ti);  
           ti._taskprocessor.SynchronizationContextValue(ti._synchronizer);  
           ti.ExecuteTask();  
         }  
         catch (Exception ex)  
         {  
           //log ex  
         }  
         finally  
         {  
           try  
           {  
             ti._taskprocessor.EndTask(ti);  
           }  
           finally  
           {  
             ti._taskprocessor.SynchronizationContextValue(null);  
           }  
         }  
       }, this);  
     }  
     private void ExecuteTask()  
     {  
       if (Action != null)  
       {  
         Action.Invoke(State);  
       }  
     }  

Create a TaskProcessorSynchronizationContext derived from SynchronizationContext class. Override all the methods where the sync object got from the ctor and call the base methods.

 public class TaskSynchronizationContext : SynchronizationContext  
   {  
     private SynchronizationContext _synctx;  
     public TaskSynchronizationContext(SynchronizationContext synctx)  
     {  
       _synctx = synctx;  
       SetSynchronizationContext(synctx);  
     }  
     public override SynchronizationContext CreateCopy()  
     {  
       return _synctx.CreateCopy();  
     }  
     //..override all methods as above  
     public override void Post(SendOrPostCallback d, object state)  
     {  
       _synctx.Post(d, state);  
     }  
     public override void Send(SendOrPostCallback d, object state)  
     {  
       string status = "Success";  
       string tid = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString();  
       try  
       {  
         _synctx.Send(x =>  
         {  
           object[] temp = (Object[])x;  
           try  
           {  
             d.Invoke(temp[1]);  
           }  
           finally  
           {  
           }  
         }, state);  
       }  
       catch (Exception)  
       {  
         status = "Failed";  
       }  
       finally  
       {          
       }  
     }  
     public override int Wait(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout)  
     {  
       return _synctx.Wait(waitHandles, waitAll, millisecondsTimeout);  
     }  
   }  

Now the usage changes to this:

TaskProcessor.Current.AddTaskInQueue("SomeTaskName", action =>  
     {  
       //make call to svc to get data   
       ServiceResponse results = GetDataFromService();  
       //update UI after we get the results..   
       TaskProcessor.Current.Synchronizer.Send(uiAction =>  
       {  
         ProcessResultsAndUpdateUI(results);  
       }, null);  
     }, null, 0);  



Thursday, January 8, 2015

Creating a parallel task framework


using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading;  
 using System.Runtime.Remoting.Messaging;  
 namespace UnderstandingThreading  
 {  
   public class ParallelProcessor2  
   {  
     List<CallContext> _contexts;  
     List<Thread> _workers;  
     private ManualResetEvent _manualWait = new ManualResetEvent(true);  
     public ParallelProcessor2()  
     {  
       _workers = new List<Thread>();  
       _contexts = new List<CallContext>();  
     }  
     public void AddTask(Action taskCallback, string taskname)  
     {  
       lock (this)  
       {  
         //handle abort condition  
         int threadCnt = _contexts.Count;  
         //_contexts.Add(CallContext.SetData(threadCnt.ToString(), this););  
         //Create TaskItem  
         TaskItem tsk = new TaskItem(threadCnt, taskCallback, taskname);  
         //Spawn new thread  
         Thread t = new Thread(Consume);  
         object o = new object();  
         o = tsk;  
         if (_workers.Count == 0)  
           _manualWait.Reset();  
         _workers.Add(t);  
         t.Start(o);  
       }  
     }  
     private void Consume(object item)  
     {  
       object temp = (object)item;  
       TaskItem tsk = (TaskItem)temp;  
       //to do: code to fetch from contexts array by passing identifier name  
       try  
       {  
         tsk.ExecuteTaskItem();  
       }  
       catch (Exception ex)  
       {  
         //create a method to report exception in call context  
         //use call context to report exception  
       }  
       finally  
       {  
         //removing completed threads  
       }  
     }  
   }  
   public class TaskItem  
   {  
     private Action _taskCallback;  
     private string _taskName;  
     private int _taskCounter;  
     public TaskItem(int taskCounter, Action taskCallback, string taskname)  
     {  
       _taskCounter = taskCounter;  
       _taskCallback = taskCallback;  
       _taskName = taskname;  
     }  
     internal void ExecuteTaskItem()  
     {  
       _taskCallback();  
     }  
   }  
 }  

Wednesday, January 7, 2015

Logging: Create a wrapper around MS EntLib Logging

Create a LogManager static class in your framework.
Logger, LogEntry, ShouldLog are all provided by EntLib
LogCategory is an enum which can describe from which layer this log was generated.

public static class LogManager  
 {  
 public static void LogMessage(LogCategory category, LogPriority priority, string message)  
 {  
   string eventCategory = category.ToString();  
   LogEntry le = new LogEntry();  
   le.Priority = (int)priority;  
   le.Categories.Add(eventCategory);  
   if (Logger.ShouldLog(le))  
   {  
      le.TimeStamp = DateTime.Now;  
      le.Message = message;  
      le.ExtendedProperties.Add("Event Source:", eventCategory);  
      if (category == LogCategory.SystemErrorTrace || category == LogCategory.FatalErrorTrace)  
      {  
        le.Severity = System.Diagnostics.TraceEventType.Error;  
      }  
      try  
      {  
        Logger.Write(le);  
      }  
      catch (Exception)  
      {  
      }  
   }  
  }  
 }  

If you need to log an entity as XML:

public static void LogEntity(LogCategory category, LogPriority priority, object valueToLog, string logMessage)  
 {  
   string eventCategory = category.ToString();  
   LogEntry le = new LogEntry();  
   le.Priority = (int)priority;  
   le.Categories.Add(eventCategory);  
   if (Logger.ShouldLog(le))  
   {  
      using (StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture))  
      {  
        if (valueToLog != null)  
        {  
           try  
           {  
             stringWriter.WriteLine(logMessage);  
             // Serailize the input object to stream  
             XmlSerializer xmlSerializer = new XmlSerializer(valueToLog.GetType());  
             xmlSerializer.Serialize(stringWriter, valueToLog);  
           }  
           catch (Exception ex)  
           {  
             stringWriter.WriteLine("Something wrong"+ex.Message);  
           }  
        }  
        else  
        {  
           stringWriter.WriteLine("Entity object = null");  
        }  
        try  
        {  
           le.TimeStamp = DateTime.Now;  
           le.ExtendedProperties.Add("Event Source:", eventCategory);  
           le.Message = stringWriter.ToString();  
           if (category == LogCategory.SystemErrorTrace || category == LogCategory.FatalErrorTrace)  
           {  
             le.Severity = System.Diagnostics.TraceEventType.Error;  
           }  
           Logger.Write(le);  
        }  
        catch (Exception)  
        {  
        }  
      }  
   }  
 }  

How Logging disabling works:
Below is snippet from web.config file:

<logFilters>  
 <add categoryFilterMode="AllowAllExceptDenied" type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.CategoryFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=7fa4cc4c62ff1809"  
 name="Category Filter">  
 <categoryFilters>  
  <!--<add name="SourceTrace" />  
  <add name="ManagerTrace" />  
  <add name="ProviderTrace" />  
  <add name="InformationTrace" />  
  <add name="ServiceTrace" />-->  
 </categoryFilters>  
 </add>  
 </logFilters>  
 <categorySources>  
 ..  
 </categorySources>  


Logging will be disabled only when a category filter is commented. tracingEnabled="false" does not work.

Tuesday, January 6, 2015

Caching: Creating a wrapper around MS EntLib Caching


These are the layers through which we have sequential calls:
Client > ServiceImplementation > Manager > Provider > DataSource

A provider may call a datasource directly. Providers can also call Managers to get requested info.

Example:
* EmployeeInformationProvider requires AsianEmployees. Hence it calls EmployeeManager.GetAsianEmployees().
* EmployeeManager.GetAsianEmployees() in turn first tries to get cached asian employees else it  will get from the datasource. Here's the code:
//Inside EmployeeManager.cs  
 public List<Employee> GetAsianEmployees()  
 {  
  return CacheProvider.CachedAsianEmployees();  
 }  
 //Inside CacheProvider.cs  
 public static CachedAsianEmployees()  
 {  
  List<Employee> employees = CacheUtility.RetrieveItem<List<Employee>>("AsianEmployeesPolicy", "AsianEmployees");  
 }
...where
AsianEmployeesPolicy = policy name
AsianEmployees = key name  

Now the CacheUtility class:
public static T RetrieveItem<T>(string policy, string keyname)  
 {  
   T res = default(T);  
      //create a tag named '<policy name="AsianEmployeesPolicy">' in config file.  
      //inside that place a provider tag which has the filename and assembly. It will have description and expiry time subtags  
   //read policy tag from config file  
   //CachingPolicy is a class with properties such as Name, ProviderInfo.  
   CachingPolicy p = CachingPolicyUtility.GetPolicy(policy);  
   if (p != null)  
   {  
     //inner implementation is upto you. Basically what this code does is initiate an activator.getinstance of the full file name with assembly that  
      //we had provided in the policy tag in our config.  
      //that provider file has certain methods like RetrieveItem which we need to invoke  
      //providers can be SlidingExpirationCacheProvider, StaticExpirationCacheProvider or SqlDependencyCacheProvider all having base type CachingProvider  
      CachingProvider provider = (CachingProvider)ProviderLoader.LoadProvider(p.ProviderInfo, typeof(CachingProvider));  
      res = (T)provider.RetrieveItem(keyname);  
   }   
   return res;  
 }  

Lets see an implementation of SlidingExpCacheProvider
Inherit some base class with operations such as StoreItem, RetrieveItem, ExpiryTime property in SlidingExpCacheProvider like SlidingExpCacheProvider: BaseCacheProvider

public class SlidingExpCacheProvider: BaseCacheProvider  
 {  
 void Init()  
 {  
 //get expiry time etc..in some private variable to use in GetExpTime property here ..  
 //also set a default time if exp time was not provided...  
 }  
 //override as necessary or stick to default implementation  
 public override object RetrieveItem(string key)  
 {  
 //CacheManager is from MS.EntLib.Caching  
   CacheManager cacheManager = CacheFactory.GetCacheManager();  
   return cacheManager[key];  
 }  
 public override void StoreItem(string key, object item)  
 {  
   double time = Convert.ToDouble(_exptime, CultureInfo.InvariantCulture);  
   //CacheManager is from MS.EntLib.Caching  
   CacheManager cacheManager = CacheFactory.GetCacheManager();  
   cacheManager.Add(key, item, CacheItemPriority.Normal, null, new SlidingTime(TimeSpan.FromMinutes(time)));  
 }  
 }

StaticExpCacheProvider is very similar to SlidingExpCacheProvider with the following differences:
*//Add item to cache 
cacheManager.Add(key, item, CacheItemPriority.Normal, null, new AbsoluteTime(DateTime.Now.AddSeconds(time)));
* Sliding exp: Cached element will expire after specified expiry time elasped after last access.
* Static: Element expires after the specified exp time. 

Coding Experiences Part 3

Points to be covered:


  • 1. Create a user control to simplify WPF forms.(covered in previous post)
  • 2. Use Strategy pattern in a complex decision making scenario.
  • 3. Converters (this post) (covered in previous post)
  • 4. Create a template to make form creations faster (this post)
  • 5. Create a common print template to print all forms in WPF
Create a Master Page like template for faster form creations in WPF

FormTemplate here is a user control just like a master page, with dependency properties, placeholders for consumer views and common controls

Create a FormTemplate user control class like this:
InputControlsPlaceHolder is an example placeholder where the consumer will have to provide controls.
FormTitle is a property bound to a label in the usercontrol xaml, which consumers can set it.

public class EntryFormTemplate : UserControl  
 {  
      public EntryFormTemplate()  
      {  
           Initialize();  
      }  
      private void Initialize()  
      {  
           ResourceDictionary resources = new ResourceDictionary();  
        resources.Source = new Uri("Resources/FormTemplate.xaml", UriKind.Relative);  
           this.Resources = resources;  
      }  
      public object InputControlsPlaceHolder  
      {  
           get { return (object)GetValue(InputControlsPlaceHolderProperty); }  
           set { SetValue(InputControlsPlaceHolderProperty, value); }  
      }  
      // Using a DependencyProperty as the backing store for InputControlsPlaceHolder. This enables animation, styling, binding, etc...  
      public static readonly DependencyProperty InputControlsPlaceHolderProperty =  
           DependencyProperty.Register("InputControlsPlaceHolder", typeof(object), typeof(EntryFormTemplate), new UIPropertyMetadata(""));  
      public string FormTitle  
      {  
           get { return (string)GetValue(FormTitleProperty); }  
           set { SetValue(FormTitleProperty, value); }  
      }  
      // Using a DependencyProperty as the backing store for FormTitle. This enables animation, styling, binding, etc...  
      public static readonly DependencyProperty FormTitleProperty =  
           DependencyProperty.Register("FormTitle", typeof(string), typeof(EntryFormTemplate), new UIPropertyMetadata("Enter some title here."));  
 }  

Now you need to add this XAML file as a resource (explaination given at the end of this post):

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">  
  <!--All your common styles should be placed here-->  
  <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource TextBoxStyle}">  
   <Style.Setters>  
    <Setter Property="MinWidth" Value="100"></Setter>  
    <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(uc:DataFormItem.LabelText), diag:PresentationTraceSources.TraceLevel=High}"/>  
   </Style.Setters>  
  </Style>  
  <!--Converters-->  
  <conv:RadioConverter x:Key="enumConverter" />  
  <Style TargetType="{x:Type uc:FormTemplate}">  
   <Setter Property="Template">  
    <Setter.Value>  
     <ControlTemplate TargetType="{x:Type uc:FormTemplate}">  
      <Grid>  
       <StackPanel>  
        <Label Style="{StaticResource TitleLabelStyle}" Content="{Binding FormTitle, FallbackValue=Title, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type uc:FormTemplate}}}"/>  
        <ScrollViewer>  
         <ContentControl Height="auto" Content="{Binding InputControlsPlaceHolder, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type uc:FormTemplate}}}"/>  
         <!--Also include all common controls here with their bindings-->  
        </ScrollViewer>  
       </StackPanel>  
      </Grid>  
     </ControlTemplate>  
    </Setter.Value>  
   </Setter>  
  </Style>  
 </ResourceDictionary> 

Why was this done 

Why did we put the style in resource file and not in a user control XAML?

You cannot use named controls inside a user control which will be consumed by other views (this was the issue faced) The workaround was to create a user control class and give it a look by loading the style from the resource dictionary. Define your placeholder dependency properties here.

  <ContentControl Height="auto" Content="{Binding InputControlsPlaceHolder, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type uc:FormTemplate}}}"/>  Why is this done?

Relative source is important here. We will provide the controls for input placeholder in the consumer view, but we'll also have to take care that the properties of those controls will have the consumer VM as its data source.

Coding Experiences Part 2

Points to be covered:


  • 1. Create a user control to simplify WPF forms.
  • 2. Use Strategy pattern in a complex decision making scenario.
  • 3. Converters (this post)
  • 4. Create a template to make form creations faster
  • 5. Create a common print template to print all forms in WPF



Use datatemplates to switch views based on conditions

In your view place this in Resources tag


 <ControlTemplate x:Key="XYZ">  
 <local:XYZDetailsView DataContext="{Binding SelectedViewItem}"/>  
 </ControlTemplate>  

Then put a datatrigger in a Control style. When the bound property from the view model matches with the value, the static resource defined in your resources will define your control's template.


 <Grid>  
 <Control>  
  <Control.Style>  
   <Style>  
    <Style.Triggers>  
      <DataTrigger Binding="{Binding Path=SelectedViewItem.Type}" Value="XYZ">  
       <Setter Property="Control.Template" Value="{StaticResource XYZ}" />  
      </DataTrigger>  
    </Style.Triggers>  
   </Style>  
  </Control.Style>  
 </Control>  
 </Grid>  

Multi Datatriggers OR conditon example

Following example demonstrates an OR condition used in a multi data trigger

<TextBlock>
   <TextBlock.Style>  
      <Style TargetType="TextBlock" BasedOn="{StaticResource dd}">  
        <Setter Property="Text" Value="" />  
        <Style.Triggers>  
           <MultiDataTrigger>  
             <MultiDataTrigger.Conditions>  
                <Condition Binding="{Binding EmpInformation.EmpType}" Value="PE" />  
             </MultiDataTrigger.Conditions>  
             <Setter Property="Text" Value="Permenant Employee" />  
           </MultiDataTrigger>  
           <MultiDataTrigger>  
             <MultiDataTrigger.Conditions>  
                <Condition Binding="{Binding EmpInformation.EmpType}" Value="Permenant Employee" />  
             </MultiDataTrigger.Conditions>  
             <Setter Property="Text" Value="Permenant Employee" />  
           </MultiDataTrigger>  
        </Style.Triggers>  
      </Style>  
   </TextBlock.Style>  
 </TextBlock>  

Monday, January 5, 2015

Some experiences and ideas in coding Part 1

Points to be covered:


  • 1. Create a user control to simplify WPF forms. (this post)
  • 2. Use Strategy pattern in a complex decision making scenario.
  • 3. Converters
  • 4. Create a template to make form creations faster
  • 5. Create a common print template to print all forms in WPF



Create a user control to simplify WPF forms.

First define a style in your resource file:


 <!---MyDataForm Related Styles-->  
   <Style TargetType="{x:Type uc:MyDataForm}">  
     <Setter Property="ItemsPanel">  
       <Setter.Value>  
         <ItemsPanelTemplate>  
           <StackPanel Orientation="{Binding Orientation, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type uc:MyDataForm}}}"/>  
         </ItemsPanelTemplate>  
       </Setter.Value>  
     </Setter>  
     <Setter Property="Template">  
       <Setter.Value>  
         <ControlTemplate TargetType="{x:Type uc:MyDataForm}">  
           <Border Background="{TemplateBinding Background}"  
               BorderBrush="{TemplateBinding BorderBrush}"  
               BorderThickness="{TemplateBinding BorderThickness}">  
             <ItemsPresenter />  
           </Border>  
         </ControlTemplate>  
       </Setter.Value>  
     </Setter>  
   </Style>  
   <ControlTemplate x:Key="ConfirmationTemplate" TargetType="{x:Type uc:MyDataFormItem}">  
     <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Margin}">  
       <DockPanel LastChildFill="False">  
         <TextBlock Style="{DynamicResource TextGray13BoldLbl}" DockPanel.Dock="Top" Margin="10,1,0,0" Text="{Binding Path=(uc:MyDataFormItem.LabelText)}" />  
         <ContentPresenter Margin="10,0,0,0" />  
       </DockPanel>  
     </Border>  
   </ControlTemplate>  
   <ControlTemplate x:Key="EntryFormTemplate" TargetType="{x:Type uc:MyDataFormItem}">  
     <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Margin}">  
       <DockPanel LastChildFill="False">  
         <Label Style="{StaticResource NewDesignFormInputLabelStyle}" DockPanel.Dock="Bottom" Margin="5,1,0,0"   
                   Content="{Binding Path=(uc:MyDataFormItem.LabelText), Converter={StaticResource UpperCaseConv}}" />  
         <ContentPresenter Margin="2,0,0,0" />  
       </DockPanel>  
     </Border>  
   </ControlTemplate>  
   <Style TargetType="{x:Type uc:MyDataFormItem}">  
     <Setter Property="Template" Value="{StaticResource EntryFormTemplate}"/>  
     <Style.Triggers>  
       <DataTrigger Binding="{Binding Path=(uc:MyDataFormItem.IsConfirmation)}" Value="True">  
         <Setter Property="Template" Value="{StaticResource ConfirmationTemplate}"/>  
       </DataTrigger>  
       <DataTrigger Binding="{Binding Path=Visibility}" Value="Collapsed">  
         <Setter Property="Template">  
           <Setter.Value>  
             <ControlTemplate TargetType="{x:Type uc:MyDataFormItem}">  
               <Border Visibility="Collapsed"/>  
             </ControlTemplate>  
           </Setter.Value>  
         </Setter>  
       </DataTrigger>  
     </Style.Triggers>  
   </Style>  

Then create a class MyDataForm which is a user control:


  public class MyDataForm : ItemsControl  
   {  
     static MyDataForm()  
     {  
       DefaultStyleKeyProperty.OverrideMetadata(typeof(MyDataForm), new FrameworkPropertyMetadata(typeof(MyDataForm)));  
       IsTabStopProperty.OverrideMetadata(typeof(MyDataForm), new FrameworkPropertyMetadata(false));  
     }  
     public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register("Orientation", typeof(Orientation), typeof(MyDataForm), new FrameworkPropertyMetadata(Orientation.Vertical));  
     public Orientation Orientation  
     {  
       get { return (Orientation)GetValue(OrientationProperty); }  
       set  
       {  
         SetValue(OrientationProperty, value);  
       }  
     }  
     protected override bool IsItemItsOwnContainerOverride(object item)  
     {  
       return item is MyDataForm || item is MyDataFormItem;  
     }  
     protected override DependencyObject GetContainerForItemOverride()  
     {  
       return new MyDataFormItem();  
     }  
   }  



Then create a class MyDataFormItem which is a user control:


  public class MyDataFormItem : ContentControl  
  {  
     static MyDataFormItem()  
     {  
       DefaultStyleKeyProperty.OverrideMetadata(typeof(MyDataFormItem), new FrameworkPropertyMetadata(typeof(MyDataFormItem)));  
       IsTabStopProperty.OverrideMetadata(typeof(MyDataFormItem), new FrameworkPropertyMetadata(false));  
     }  
     public static readonly DependencyProperty LabelTextProperty = DependencyProperty.RegisterAttached("LabelText", typeof(string), typeof(MyDataFormItem));  
     public static string GetLabelText(DependencyObject obj)  
     {  
       return (string)obj.GetValue(LabelTextProperty);  
     }  
     public static void SetLabelText(DependencyObject obj, string value)  
     {  
       obj.SetValue(LabelTextProperty, value);  
     }  
     public static bool GetIsConfirmation(DependencyObject obj)  
     {  
       return (bool)obj.GetValue(IsConfirmationProperty);  
     }  
     public static void SetIsConfirmation(DependencyObject obj, bool value)  
     {  
       obj.SetValue(IsConfirmationProperty, value);  
     }  
     // Using a DependencyProperty as the backing store for IsConfirmation. This enables animation, styling, binding, etc...  
     public static readonly DependencyProperty IsConfirmationProperty =  
       DependencyProperty.RegisterAttached("IsConfirmation", typeof(bool), typeof(MyDataFormItem), new UIPropertyMetadata(false));  
 }  


Usage in XAML


 <TextBox uc:MyDataFormItem.LabelText="Contact name" x:Name="txtContactName" Text="{Binding ContactName}" TextWrapping="Wrap"></TextBox>  

Other points covered in other posts