Tag Archives: WPF

Get compile time support for Property names

Hello,

Many times we need to use string values for C# properties. Although this is not a common practise, we may not have choice sometimes e.g. using RX –

Observable.FromEventPattern<PropertyChangedEventArgs>(this,"PropertyChanged")
 .Where(e => e.EventArgs.PropertyName == "SearchString")
 .Subscribe(_ => DoSomeWork());

In this case,  we have to pass the string value (name) of the property for RX Observable to work. I am interested in subscribing to this event of my property(which is in turn bound to textbox on view).

So I can either pass the string literal which provides no compile time support or I can use expression trees to pass an expression and retrieve string name literal at runtime as follows:

Observable.FromEventPattern<PropertyChangedEventArgs>(this,"PropertyChanged")
 .Where(e => e.EventArgs.PropertyName == GetPropertyName(() => SearchString))
 .Subscribe(_ => DoSomeWork());

This works because I have written a private function in my class to extract the actual string name from the propertyname. The function is as follows:

public static string GetPropertyName<T>(Expression<Func<T>> expression)
{
    MemberExpression memberExpression = (MemberExpression)expression.Body;
    return memberExpression.Member.Name;
}

Have a nice day!

Advertisements

Working with DataTemplateSelector

Hello,

When you are working with DataTemplateSelector, make sure that you call the InitialiseComponent() method at the end of the constructor in codebehind.  Have a look at the following code:

 public partial class MainWindow : Window
 {
 public MainWindow()
 {
 

 Collection = new ObservableCollection<INotifyPropertyChanged>();
 Collection.Add(new ViewModel1());
 Collection.Add(new ViewModel2());
 Collection.Add(new ViewModel1());
 Collection.Add(new ViewModel2());
 Collection.Add(new ViewModel1());
 Collection.Add(new ViewModel2());

 InitializeComponent();  //Don't put this as 1st line

 }


 public ObservableCollection<INotifyPropertyChanged> Collection { get; set; }
 
 }

If I just move the call to InitialiseComponent() at the begining of the constructor as the first statement, i don’t get any runtime errors or even any exception on output window but my view renders blank. The main cause being that the binding is already done before InitialiseComponent() and if i set the Collection property after that, it doesn’t do anything because the opportunity has passed.

My Collection property is bound to an ItemsControls in XAML and this ItemsControl uses an ItemTemplateSelector to select the correct DataTemplate for the showing the view.

 

Be careful with Data Template markup

This one is rather for WPF beginners but even after working on WPF for few years, I happened to make this mistake and overlooked it. So just wanted to highlight it for benefit of others…..

When you define a DataTemplate, make sure that you define the x:Key attribute before any other attributes, otherwise it will not get picked up because of the ForwardOnly usage policy of static resource.  I tried the following:

<DataTemplate DataType="wpfApplication1:ViewModel1" x:Key="DataTemplate1" >
 <wpfApplication1:View1/>
 </DataTemplate>

and it gave me the famous error:  “Cannot find resource named ‘DataTemplate2’. Resource names are case sensitive.”

Just by changing the order of the x:Key attribute and putting it before DataType attribute, solved this error. So be careful 🙂

Have a nice day!