Tuesday, May 25, 2010

A case for a nameof() operator

Refactoring your code has come a long way, especially with tools like Resharper one seldom worries about changing namespaces, renaming classes or extracting methods.
But one major breaking point still exists: Using property names as strings. And C# contains two very popular interfaces in need of property name strings.
INotifyPropertyChanged:
public string Name {
  get { return name; }
  set {
   name = value;
   InvokePropertyChanged("Name");
  }
 }

and WPFs dependency properties:
public static readonly DependencyProperty 
  ViewModelProperty = 
    DependencyProperty.Register("ViewModel",
                                typeof(MyViewModel),
                                typeof(UserView));

Both interfaces, especially with the rise of WPF/Silverlight applications, are used quite a lot. And it is not only the newbie programmer who will inadvertently break some code because he forgot to change the string when renaming a property. And while WPFs dependency properties will at least throw an exception in most cases bugs will slip in for the property changes or other interfaces which rely on the correct strings.
Since the beginning of C# people searched for solutions which do not break on refactoring, and at least since LINQ there is a viable workaround as LINQ queries have the unique property of containing string representations on their member expression parts:
public string ParsePropertyName<T>
(Expression<Func<T>> expression)
{
return ((MemberExpression)expression.Body).Member.Name;
}
...
public string Name {
  get { return name; }
  set {
   name = value;
   InvokePropertyChanged(
     ParsePropertyName(()=>this.Name);
  }
 }
While this simple solution has drawbacks (e.g. when no instance of a class is available) it seems to be used quite often as its described and discussed quite a lot. E.g. here here here here or here.

Even though the solution remains what it is: a hacky workaround.
And that is why I would propose adding a simple nameof() operator instead. It would allow us to get rid of all the fluff we add to get the name of a property and would let us write this code instead:
Code:
public string Name {
  get { return name; }
  set {
   name = value;
   InvokePropertyChanged(nameof(Name));
  }
 }

The compiled code would still look the same, without the performance drawbacks of LINQ queries, and it wouldn't break on refactoring. As an added bonus we get the functionality on methods, events... you name it.
I rest my case, what does the jury think?

Submit this story to DotNetKicks

Thursday, May 20, 2010

Committing bound cell changes immediately in WPF Datagrid

The WPF DataGrids default mode of operation is committing all changes on a per-row edit instead of a per-cell edit. In this post we will see how to change that behavior to do a per-cell commit regardless of the bound object's capabilities.

But first a little bit about the workings of the DataGrid.
When binding data in a WPF DataGrid it holds all changes to the data in an intermediary object. If the user edits a cell the changes will be done only in this intermediary object, the exception being if the bound object does implement IEditableObject in which case the DataGrid uses the object's edit capabilities instead.
But if we do not have an IEditableObject to bind to all changes made inside the row will only be committed to the bound object once the row edit ends. If we still need to commit on a cell by cell basis we need to attach a handler to the CellEditEnding event of the grid and use the following code in the handler.

private bool isManualEditCommit;
private void HandleMainDataGridCellEditEnding(
  object sender, DataGridCellEditEndingEventArgs e) 
{
 if (!isManualEditCommit) 
 {
  isManualEditCommit = true;
  DataGrid grid = (DataGrid)sender;
  grid.CommitEdit(DataGridEditingUnit.Row, true);
  isManualEditCommit = false;
 }
}

This will update the bound object whenever a cell edit is ending, i.e. whenever the cell looses focus.

Submit this story to DotNetKicks