Update the Model on enter key pressed with Angularjs

In angularjs, the ngModel directive is used for setting up a two way data binding between an input element and the underlying model.
By default, the model is updated when the input value changes, for example while the user is typing.

Based on your scenario, having the model updated immediately may or may not be desierable.
With version 1.3, angularjs introduces the ngModelOptions directive which gives you better control of when / how the model is updated from the view.

In my case, I needed to prevent the model from being updated until the user pressed ‘enter’, or until the input element lost focus.

Using ngModelOptions, you can specify which event will trigger the model update like this ng-model-options=”{updateOn:’eventName‘}”, so if you want the model to be updated when the input element loses focus, you need the update to happen on the ‘blur’ event; ng-model-options=”{updateOn:’blur’}”

<div ng-controller="myAppController as ctrl">
    		<input type="text" ng-model="ctrl.theValue" ng-model-options="{updateOn:'blur'}" />
</div>

 Note! If you want to prevent the ngModel directive from updating the model altogether, you can specify an ‘invalid’ value for updateOn, for example ng-model-options=”{updateOn:’none‘}”.

The next thing to do is update the model when the ‘enter’ key is pressed.
To achieve this, you need control of when the ngModel directive updates the model. The API for the ngModel directive is surfaced through the ngModelController, so by getting a reference to the ngModelController, you can manually trigger a model update.
All of this can be done using a custom directive which is applied to the input element.

angular.module('myApp').directive("updateModelOnEnterKeyPressed", function() {
		    return {
		        restrict: 'A',
		        require: 'ngModel',
		        link: function (scope, elem, attrs, ngModelCtrl) {
		            elem.bind("keyup",function(e) {
		                if (e.keyCode === 13) {
		                    ngModelCtrl.$commitViewValue();
		                }
		            });
		        }
		    }
		});

The key parts of the directive are getting a reference to the ngModelController using ‘require’ in the DDO, and calling the $commitViewValue() function to trigger the model update.

By applying the directive to the input element, the model will be updated whenever the user presses ‘enter’ while the input element accepts input, and when the input element loses focus.

<div ng-controller="myAppController as ctrl">
	<input type="text" ng-model="ctrl.theValue" ng-model-options="{updateOn:'blur'}" data-update-model-on-enter-key-pressed/>
</div>
Posted in angularjs, HTML, JavaScript | 3 Comments

Custom Markup Extension with bindable properties

Download Source Code

Microsoft added custom markup extensions to SL5, but they did not provide built-in support for binding to the properties of CME’s. If you’re using CME’s to manipulate your UI, trying to make the UI react to changes in your View Model after the UI has loaded will not work.

When the UI loads, the runtime finds your CME’s and calls the ProvideValue method of your CME to get the value that should be applied to the UI element. The problem is that there’s no way to force the runtime to call ProvideValue again when something has changed in your View Model, so the UI will not react to changes in your VM.

Below is an example of how you could use a CME (called ConvertBooleanToVisibility) to toggle the visibility of a UI element based on the state of two properties in your View Model. Doing this without using a CME would require you to create a third “aggregate” property in your View Model to combine the values of the two main properties, bind to that aggregated property and use a ValueConverter to convert from boolean to Visibility.

<Rectangle Visibility="{local:ConvertBooleanToVisibility Value1={Binding Path=IsVisible}, Value2={Binding Path=IsVisible2}}"/>

As you can see, I’ve used a CME with two properties, Value1 and Value2, that binds to two properties in the View Model. When these values change, the Visibility property of the Rectangle is changed.

The trick to make this work is the following:

  • Instead of inheriting from MarkupExtension, you need to inherit from DependencyObject and implement the IMarkupExtension<object> interface
  • Add dependency properties to the CME, so that you can use bindings. The DP’s must have a property changed callback.
  • In ProvideValue, get a reference to the UI element and property that the CME is applied to. You’ll need these references to manually update the UI element when your View Model property changes. You’ll also need to subscribe to the DataContextChanged event for the UI element so you’ll know when a View Model has been attached. This is necessary because at the time the runtime calls ProvideValue the first time, the View Model may not yet be attached, so you need to modify the binding to point to the correct source once you have a View Model in scope.
  • When the View Model is attached, the DataContextChanged event will be raised. This will allow you to get the binding expressions for your dependency properties. To get the binding expressions for your properties instead of the values, use the ReadLocalValue method instead of GetValue(…). Once you have the binding expressions, copy the binding and remap the binding source so that it points to the attached View Model. Then apply the new bindings to the dependency properties of the CME.
  • Once the bindings are in place, this will make the property changed callbacks to get called when the dependency properties are changed. In the callbacks, call a method that calculates the composite value of the the two DPs and use the UI element and property reference obtained in ProvideValue (step 2) to update the UI element.

Below is a complete listing of the implementation of this Custom Markup Extension.

using System;
using System.Reflection;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;
using System.Xaml;

namespace CMEWithBinding
{
    public class ConvertBooleanToVisibilityExtension : DependencyObject, IMarkupExtension<object>
    {
        private object _target;
        private object _targetProperty; // Can be PropertyInfo or Binding

        #region Value1
                
        public static readonly DependencyProperty Value1Property =
            DependencyProperty.Register("Value1", typeof(bool), typeof(ConvertBooleanToVisibilityExtension),
                new PropertyMetadata((bool)false,
                    new PropertyChangedCallback(OnValue1Changed)));
        

        public bool Value1
        {
            get { return (bool)GetValue(Value1Property); }
            set { SetValue(Value1Property, value); }
        }
                
        private static void OnValue1Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((ConvertBooleanToVisibilityExtension)d).OnValue1Changed(e);
        }

        protected virtual void OnValue1Changed(DependencyPropertyChangedEventArgs e)
        {            
            UpdateTarget();
        }

        #endregion

        #region Value2

        /// <summary>
        /// Value2 Dependency Property
        /// </summary>
        public static readonly DependencyProperty Value2Property =
            DependencyProperty.Register("Value2", typeof(bool), typeof(ConvertBooleanToVisibilityExtension),
                new PropertyMetadata((bool)false,
                    new PropertyChangedCallback(OnValue2Changed)));

        /// <summary>
        /// Gets or sets the Value2 property.  This dependency property 
        /// indicates ....
        /// </summary>
        public bool Value2
        {
            get { return (bool)GetValue(Value2Property); }
            set { SetValue(Value2Property, value); }
        }

        /// <summary>
        /// Handles changes to the Value2 property.
        /// </summary>
        private static void OnValue2Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((ConvertBooleanToVisibilityExtension)d).OnValue2Changed(e);
        }

        /// <summary>
        /// Provides derived classes an opportunity to handle changes to the Value2 property.
        /// </summary>
        protected virtual void OnValue2Changed(DependencyPropertyChangedEventArgs e)
        {
            UpdateTarget();
        }

        #endregion



        #region Properties
        
        private bool _value1CompareTo = true;
        public bool Value1CompareTo
        {
            get { return this._value1CompareTo; }
            set { this._value1CompareTo = value; }
        }

        private bool _value2CompareTo = true;

        public bool Value2CompareTo
        {
            get { return this._value2CompareTo; }
            set { this._value2CompareTo = value; }
        }



        #endregion

        public ConvertBooleanToVisibilityExtension()
        {
                        
        }
        
        public object ProvideValue(IServiceProvider serviceProvider)
        {
            IProvideValueTarget ipValueTarget = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
                        
            if (this._target == null)
            {
                if (ipValueTarget.TargetObject is FrameworkElement)
                {
                    FrameworkElement target = (FrameworkElement)ipValueTarget.TargetObject;
                    target.DataContextChanged += new DependencyPropertyChangedEventHandler(target_DataContextChanged);
                }

                this._target = ipValueTarget.TargetObject;
                this._targetProperty = ipValueTarget.TargetProperty;
            }

            Visibility vis = CalcCompositeValue();
            return vis;
        }
        

        void target_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            BindingExpression value1BEX = ReadLocalValue(ConvertBooleanToVisibilityExtension.Value1Property) as BindingExpression;
            BindingExpression value2BEX = ReadLocalValue(ConvertBooleanToVisibilityExtension.Value2Property) as BindingExpression;
            
            if (value1BEX != null && BindingSourceNotSet(value1BEX.ParentBinding))
            {
                Binding old = value1BEX.ParentBinding;
                ClearValue(ConvertBooleanToVisibilityExtension.Value1Property);
                Binding newBinding = CopyBinding(ref e, old);
                BindingOperations.SetBinding(this, ConvertBooleanToVisibilityExtension.Value1Property, newBinding);
            }

            if (value2BEX != null && BindingSourceNotSet(value2BEX.ParentBinding))
            {
                Binding old = value2BEX.ParentBinding;
                ClearValue(ConvertBooleanToVisibilityExtension.Value2Property);
                Binding newBinding = CopyBinding(ref e, old);
                BindingOperations.SetBinding(this, ConvertBooleanToVisibilityExtension.Value2Property, newBinding);
            }
        }
        

        private bool BindingSourceNotSet(Binding binding)
        {
            return binding.Source == null && binding.RelativeSource == null;
        }

        private static Binding CopyBinding(ref DependencyPropertyChangedEventArgs e, Binding old)
        {
            Binding b = new Binding();
            b.BindsDirectlyToSource = old.BindsDirectlyToSource;
            b.Converter = old.Converter;
            b.ConverterCulture = old.ConverterCulture;
            b.ConverterParameter = old.ConverterParameter;
            b.FallbackValue = old.FallbackValue;
            b.Mode = old.Mode;
            b.NotifyOnValidationError = old.NotifyOnValidationError;
            b.Path = old.Path;
            if (old.RelativeSource != null)
            {
                b.RelativeSource = old.RelativeSource;
            }

            if (old.ElementName != null)
            {
                b.ElementName = null;
            }
            
            if (old.ElementName == null && b.RelativeSource == null)
            {
                b.Source = e.NewValue;
            }

            b.StringFormat = old.StringFormat;
            b.TargetNullValue = old.TargetNullValue;
            b.UpdateSourceTrigger = old.UpdateSourceTrigger;
            b.ValidatesOnDataErrors = old.ValidatesOnDataErrors;
            b.ValidatesOnExceptions = old.ValidatesOnExceptions;
            b.ValidatesOnNotifyDataErrors = old.ValidatesOnNotifyDataErrors;
            
            return b;
        }
        

        private void UpdateTarget()
        {
            Visibility vis = CalcCompositeValue();
            if (this._target != null && this._targetProperty != null && !(this._target is Binding))
            {
                if (this._targetProperty is PropertyInfo)
                {
                    PropertyInfo pi = (PropertyInfo)this._targetProperty;
                    pi.SetValue(this._target, vis, null);
                }
            }
        }        

        private Visibility CalcCompositeValue()
        {
            bool b = (this.Value1 == this._value1CompareTo && this.Value2 == this._value2CompareTo);
            Visibility vis = b ? Visibility.Visible : Visibility.Collapsed;
            return vis;
        }
    } 

}

 

Download Source Code

Posted in .NET General, Silverlight | Leave a comment

Change tracking in object graph

Download Source Code from here

On this project I was working on, I had to monitor objects and object graphs for changes so I could display this information to the user. Having looked around the internet for solutions, I could not find any single solution that I felt suited my needs perfectly, so I decided to take a stab at the problem myself.

The requirements for my change tracker was the following:

  • Very easy to use, preferably a single line of code to enable and disable change tracking for an object and its entire object graph
  • The solution had to support an unknown object graph depth and automatically adapt to  changes in the graph depth (attach to new objects added and detach from objects removed, including items added to and removed from collections)
  • Automatically listen for changes to all properties of objects, but support adding exceptions for properties that should not be tracked (if any)
  • Support explicitly defining which properties that should be change tracked
  • Except for implementing the INotifyPropertyChanged and INotifyCollectionChanged interfaces, there should be no other requirements imposed on the objects for enabling change tracking
  • Change notifications should be easy to subscribe to and contain data about the changes that had been made

To jump to the conclusion, what I ended up with was the following, which attaches to an item and starts listening for changes to the item and its entire object graph:

var observer = ObjectGraphObserver.AttachObserver(this.Item1, 
                (s, e) => DumpChangeTrackingInfo(s, e));

//....and detach when the time comes
ObjectGraphObserver.DetachObserver(observer);

 

The first line of code creates an instance of the ObjectGraphObserver which starts listening for changes made to an object (“Item1”) and its object graph by passing in the object root as the first argument. The second argument passed to the method is the callback that should be called when a change occurs. In this case I call a method which dumps information about the change that occurs, but you could also do all other sorts of things like (conditionally) raising a dirty flag to indicate to the user that a change has occurred.

The DumpChangeTrackingInfo method looks like this. You can see I’m using the data passed along from the observer to provide some “useful” information to the user.

private void DumpChangeTrackingInfo(object sender, ObservedPropertyChangedEventArgs e)
{
  if (e is ObjectChangedEventArgs)
  {
      ObjectChangedEventArgs oce = (ObjectChangedEventArgs)e;
      
      StringBuilder sb = new StringBuilder(this._changeTrackingData);
      sb.AppendLine();
      sb.AppendFormat("Property name = '{0}', Sender name = '{2}'", 
          oce.PropertyName, oce.Sender, oce.SenderName);

      this.ChangeTrackingData = sb.ToString();

  }
  else if (e is CollectionChangedEventArgs)
  {
      CollectionChangedEventArgs cce = (CollectionChangedEventArgs)e;
      
      StringBuilder sb = new StringBuilder(this._changeTrackingData);
      sb.AppendLine();
      sb.AppendFormat("Property name = '{0}', Sender name = '{2}', Action = '{3}'", 
          cce.PropertyName, cce.Sender, cce.SenderName, cce.Action);

      if (cce.Action == NotifyCollectionChangedAction.Add)
      {
          for (int i = 0; i < cce.NewItems.Count; i++)
          {
              Level1Item lvlItem = (Level1Item)cce.NewItems[i];
              sb.AppendLine();
              sb.AppendFormat("\t Name = '{0}'", lvlItem.Name);
          }
      }

      this.ChangeTrackingData = sb.ToString();                
  }
}

The AttachObserver and DetachObserver methods looks like this:

public static ObjectGraphObserver AttachObserver(object target, 
	Action<object, ObservedPropertyChangedEventArgs> handler)
{
  ObjectGraphObserver observer = new ObjectGraphObserver(target);
  observer.ChangeDetected += new EventHandler<ObservedPropertyChangedEventArgs>(handler);
  return observer;
}

public static void DetachObserver(ObjectGraphObserver observer)
{
  if (observer != null)
  {
      observer.Detach();
      observer._changeDetectedHandler = null;
      observer = null;
  }
}

When an ObjectGraphObserver is created by passing the root object to the constructor, reflection is used to walk the object graph and setting up the change monitoring. By using reflection, you all know that this solution will not be extremely fast for setting up the change tracking for very large object graphs, but for my needs it was more than fast enough. I usually make sure to create the observers on a separate thread to not block the UI or other processes. The ObjectGraphObserver also has constructor overloads that lets you specify a max depth at which the observer stops tracking changes.

The ObjectGraphObserver passes two kinds of event args to the callback when a change occurs; the ObjectChangedEventArgs for changes to properties of an object, and the CollectionChangedEventArgs when a collection changes (items being added or removed). Both event args contains information about the object that was changed and which property of the object that was affected. The CollectionChangedEventArgs also contains information about the item that was added to or removed from the collection.

To prevent an object in the object graph that implements INotifyPropertyChanged or INotifyCollectionChanged from being change tracked, you can decorate a property with the NonChangeTrackableAttribute attribute. This will make the ObjectGraphObserver ignore that property when it walks the object graph. All properties of a type that implements INotifyPropertyChanged / INotifyCollectionChanged not tagged by the NonChangeTrackableAttribute attribute will be tracked (unless an explicit list of types and properties are specified, which I’ll demonstrate shortly).

The code snippet below shows an example of using the NonChangeTrackableAttribute attribute.

public class Level2ItemWithNonChangeTrackableProp : INPC
{
   private string _name;
   public string Name
   {
       get { return _name; }
       set { SetProperty(ref this._name, value, () => this.Name); }
   }

   // Updating the Child properties will not trigger a change notification 
   // through the ObjectGraphObserver 
   private Level2Item _child;
   [NonChangeTrackable]  
   public Level2Item Child
   {
       get { return _child; }
       set { SetProperty(ref this._child, value, () => this.Child); }
   }
}

The above example shows how to set up exceptions for properties that should NOT be tracked. I also needed to support the opposite approach; explicitly specifying only the types and properties that should be tracked. Using this approach, only the types and properties explicitly defined in a mapping list are being tracked, all the other types and properties are being ignored.

The following example shows how to create an observer which listens for and notifies about changes made to the “Name” and “Count” properties of “Level2Item” instances. I’ve also set the max depth to 10, meaning the observer will not monitor objects deeper than 10 levels from the root object.

 

var observer = ObjectGraphObserver.AttachObserver(this.Item3, 
                GetItem3Properties(), 10, 
                (s, e) => DumpChangeTrackingInfo(s, e));

private Dictionary<Type, List<string>> GetItem3Properties()
{
  Dictionary<Type, List<string>> propMap = new Dictionary<Type, List<string>>();
  propMap.Add(typeof(Level2Item), new List<string> { "Name", "Count" });
  return propMap;
}

I’m not saying this is an ideal solution to the problem, but it works for good for me. There are issues regarding circular references that I do not handle. Also, the fact that I’m using reflection to set things up makes it “slow”, so if you’re planning on using the same approach, be aware of the implications of attaching to a large object (graph).

Posted in .NET General, Silverlight | Leave a comment

WCF Data Service UpdateObject gotcha

For a project I’m working on, we’re using WCF Data Services as our primary data service technology. We have created a small framework / pattern that extends the DataServiceContext and the entities being tracked, so that when any property of an entity is changed, that entity is marked as “Dirty”. When the user wants to save the data, we find the entities that are tagged as Dirty, and calls DataServiceContext.UpdateObject so any changes are can be saved to the database.

The implemenation seemed pretty straight forward, but we discovered that for some reason, not all the entities had its data updated to the database.

This is our first implementation of the ApplyChanges method that is called when the user performs a save action;

public void ApplyChanges()
{
     for (int i = 0; i < this.Entities.Count; i++)
     {
         object entity = this.Entities[i].Entity;
         if (((IEntityExtension)entity).IsDirty)
         {
             SetEntityLinks(entity);
             this.UpdateObject(entity);
         }
     }
}

 

All this looks fine, but what happens when you call UpdateObject, is that the entity (or EntityDescriptor) being updated is moved to the end of the DataServiceContext.Entities collection, which means our loop state suddenly becomes invalid. I’m sure there’s a good reason for this behavior, it just isn’t obvious.

The fix is simple enough, use a foreach loop instead of the normal for loop, and everything works just fine.

public void ApplyChanges()
{
    foreach (var entity in this.Entities.Select(c => c.Entity))
    {
        if (((IEntityExtension)entity).IsDirty)
        {
             SetEntityLinks(entity);
             this.UpdateObject(entity);
        }
    }            
}

Posted in ADO.NET Data Services | Leave a comment

A Silverlight Fade behavior

This is a simple Silverlight behavior that can be used for providing a smoother UI experience when switching between two or more controls (any FrameworkElement derived component) by applying a fade in and fade out animation to the controls being switched. It can also be used to fade a control in when the UI is loaded.

The behavior derives from System.Windows.Interactivity.Behavior<T> from the Blend SDK, so you need the System.Windows.Interactivity.dll or the Blend SDK installed to run the sample.

The code is pretty straight forward, so I’m not going to go into that (you can download it from the link at the end of this post). Instead, I’ll just show the XAML for using it:

<Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid>
            <i:Interaction.Behaviors>
                <local:FadeBehavior FrontElementName="{Binding Path=FrontElementName, Mode=TwoWay}" 
                                    Duration="00:00:01.000">
                    <local:FadeBehavior.EasingFunction>
                        <PowerEase EasingMode="EaseInOut" Power="3" />
                    </local:FadeBehavior.EasingFunction>
                </local:FadeBehavior>
            </i:Interaction.Behaviors>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <Grid x:Name="rect1" >
                <TextBlock Text="My grid 11" FontSize="48" VerticalAlignment="Center" 
                           HorizontalAlignment="Center"/>
            </Grid>
            <Grid x:Name="rect2">
                <TextBlock Text="Text in grid 2" FontSize="48" VerticalAlignment="Center" 
                           HorizontalAlignment="Center"/>
            </Grid>
            <Grid x:Name="rect3">
                <TextBlock Text="Text in grid 3" FontSize="48" VerticalAlignment="Center" 
                           HorizontalAlignment="Center"/>
            </Grid>            
        </Grid>       
                
        <Button Content="Click" Grid.Row="1" x:Name="doAnimationButton" 
                Click="doAnimationButton_Click"/>
    </Grid>

When the behavior is applied to a UI element, it will fade child elements in and out when the FrontElementName property is changed.
The FrontElementName property is used for setting what UI element should be visible at any time, and the behavior searches the UI element for a child with a matching name. When it finds a match, it fades the new element in and the old element out.

The FrontElementName property is a dependency property, so it can be databound and have its value updated from a view model as the example below shows.


        public MainPage()
        {
            InitializeComponent();
            this.DataContext = this;
            this.FrontElementName = "rect2";   
        }

        private void doAnimationButton_Click(object sender, RoutedEventArgs e)
        {            
            if (this.FrontElementName == "rect1")
            {
                this.FrontElementName = "rect3";
            }
            else
            {
                this.FrontElementName = "rect1";
            }            
        }

The behavior has two optional properties;
Duration specifies the length of the animation.
EasingFunction specifies the easing function used for the animation. The default value is CubicEase.

Download source code and demo project

Posted in Uncategorized | Leave a comment

UIElementCollection changed notification

The other day I was writing a Silverlight custom control, deriving from Grid, I needed to get notified whenever the Children collection of the Grid changed. The problem is that there’s no collection changed event being raised when a UIElementCollection changes.

So I fired up .NET Reflector and found out that there acually is a changed event being raised when the collection changes, but it’s internal only. However, since the UIElementCollection Count property is a dependency property (UIElementCollection derives from PresentationFrameworkCollection<T>), you can listen for changes to the Count dependency property using an attached property trick.

For this purpose, I created a Rx extension method that lets you subscribe to dependency property changes. This way, I get notified whenever the UIElementCollection changes.

Usage example;

// Children collection is a UIElementCollection
            var listener = ObservableEx.FromDependencyPropertyChanged(this.Children, 
                    collection => collection.Count).
                    Subscribe(x => System.Diagnostics.Debug.WriteLine("Count changed"));

 

And here’s the Rx extension method that helps me listen for the changes;

public static class ObservableEx
    {
        public static IObservable<TResult> FromDependencyPropertyChanged<TType, TResult>(
            TType target, Expression<Func<TType, TResult>> property)
            where TType : DependencyObject
        {
            if (target == null)
            {
                throw new ArgumentNullException("target", "target cannot be null");
            }

            var body = property.Body as MemberExpression;

            if (body == null)
                throw new ArgumentException("Invalid property expression", "property");

            string propertyName = body.Member.Name;

            if (body.Member is FieldInfo)
            {
                var fieldInfo = body.Member as FieldInfo;
                if (fieldInfo.FieldType == typeof(DependencyProperty))
                {
                    propertyName = propertyName.Remove(propertyName.LastIndexOf("Property"));
                }                
            }           

            var getter = property.Compile();

            return Observable.Create<TResult>(observer =>
            {
                var handler = new PropertyChangedCallback((dpo, args) => 
                    observer.OnNext((TResult)getter(target)));
                RegisterForPropertyChangedNotification(propertyName, target, handler);
                return new Action(() => { });
            });

        }

        private static void RegisterForPropertyChangedNotification(string propertyName, 
            DependencyObject element, PropertyChangedCallback callback)
        {
            Binding b = new Binding(propertyName) { Source = element };
            var prop = System.Windows.DependencyProperty.RegisterAttached(
                "__ListenAttached" + propertyName,
                typeof(object),
                element.GetType(),
                new System.Windows.PropertyMetadata(callback));

            BindingOperations.SetBinding(element, prop, b);            
        }
    }
Posted in Silverlight | 7 Comments

Missing Templates from Visual Studio 2010

The other day when I was working on a Silverlight project I couldn’t find the ‘Silverlight UserControl’ template in the Add New Item dialog…it was simply gone. Also missing was the ‘Silverlight Templated Control’ template. I’m not sure what had happened, but I had recently installed the confusing GDR1 update to the Silverlight SDK…don’t know if that’s the one that caused the problem, but it’s my number one suspect.

When I looked in the Visual Studio ItemTemplateCache, I could see that the .vstemplate file for the Silverlight UserControl template was missing from the system. Somehow it had been deleted, and I’m 100% sure I didn’t do it.

To fix the problem, I had to delete the content of the ItemTemplateCache folder;

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplatesCache\CSharp\Silverlight\1033

and then rebuild the item cache by running the following command from the Visual Studio Command Prompt; devenv /installvstemplates

Posted in Visual Studio | 1 Comment