Rockford Lhotka's Blog

Home | Lhotka.net | CSLA .NET

 Tuesday, 09 January 2007
« Rambling thoughts on pragmatic developme... | Main | Should you change values in a property s... »

Here's an issue from Windows Forms that appears to have crept into WPF as well – along with a solution (thanks to Sam Bent and Kevin Moore from the WPF team):

 

Consider a class with a property that enforces a business rule - such as that the value must be all upper case:

 

public class Test : INotifyPropertyChanged

{

  public event

    System.ComponentModel.PropertyChangedEventHandler

    PropertyChanged;

  // ...

 

  private string _data;

 

  public string Data

  {

    get

    {

      return _data;

    }

    set

    {

      _data = value.ToUpper();

      OnNotifyPropertyChanged("Data");

     }

  }

}

 

Bind this to a TextBox and type in a lower-case value. The user continues to see the lower-case value on the screen, even though the object obviously has an upper-case value. The PropertyChanged event is blissfully ignored by WPF data binding.

 

I believe this is the same "optimization" as in Windows Forms, where the assumption is that since the value was put into the object by data binding that it can’t be different from what's on the screen - so no refresh is needed. Obviously that is a unfortunate viewpoint, as it totally ignores the idea than an object might be used to centralize business logic or behavior...

 

In Windows Forms the solution to this issue is relatively simple: handle an event from the BindingSource and force the BindingSource to refresh the value. Bill McCarthy wrapped this solution into an extender control, which I included in CSLA .NET, making the workaround relatively painless.

 

In WPF the solution is slightly different, but also relatively painless.

 

It turns out that this optimization doesn’t occur if an IValueConverter is associated with the binding, and if the binding’s UpdateSourceTrigger is not PropertyChanged.

 

For the TextBox control the UpdateSourceTrigger is LostFocus, so it is good by default, but you’ll want to be aware of this property for other control types.

 

An IValueConverter object’s purpose is to format and parse the value as it flows to and from the target control and source data object. In my case however, I don’t want to convert the value at all, I just want to defeat this unfortunate “optimization”. What’s needed is an identity converter: a converter that does no conversion.

 

namespace Csla.Wpf

{

  public class IdentityConverter : IValueConverter

  {

    #region IValueConverter Members

 

    public object Convert(

      object value, Type targetType,

      object parameter, System.Globalization.CultureInfo culture)

    {

      return value;

    }

 

    public object ConvertBack(

      object value, Type targetType,

      object parameter, System.Globalization.CultureInfo culture)

    {

      return value;

    }

 

    #endregion

  }

}

 

Just configure this in your XAML:

 

<Page x:Class="PTWpf.ProjectEdit"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:csla="clr-namespace:Csla.Wpf"

    Title="Project Edit"

    >

  <Page.Resources>

    <csla:IdentityConverter x:Key="IdentityConverter" />

  </Page.Resources>

...

  <TextBox Text="{Binding Data, Converter={StaticResource IdentityConverter}}"></TextBox>

...

 

Just like that, it all works as expected and the value from the object is reflected in the UI.

On this page....
Search
Archives
Feed your aggregator (RSS 2.0)
June, 2017 (1)
May, 2017 (1)
April, 2017 (2)
March, 2017 (1)
February, 2017 (2)
January, 2017 (2)
December, 2016 (5)
November, 2016 (2)
August, 2016 (4)
July, 2016 (2)
June, 2016 (4)
May, 2016 (3)
April, 2016 (4)
March, 2016 (1)
February, 2016 (7)
January, 2016 (4)
December, 2015 (4)
November, 2015 (2)
October, 2015 (2)
September, 2015 (3)
August, 2015 (3)
July, 2015 (2)
June, 2015 (2)
May, 2015 (1)
February, 2015 (1)
January, 2015 (1)
October, 2014 (1)
August, 2014 (2)
July, 2014 (3)
June, 2014 (4)
May, 2014 (2)
April, 2014 (6)
March, 2014 (4)
February, 2014 (4)
January, 2014 (2)
December, 2013 (3)
October, 2013 (3)
August, 2013 (5)
July, 2013 (2)
May, 2013 (3)
April, 2013 (2)
March, 2013 (3)
February, 2013 (7)
January, 2013 (4)
December, 2012 (3)
November, 2012 (3)
October, 2012 (7)
September, 2012 (1)
August, 2012 (4)
July, 2012 (3)
June, 2012 (5)
May, 2012 (4)
April, 2012 (6)
March, 2012 (10)
February, 2012 (2)
January, 2012 (2)
December, 2011 (4)
November, 2011 (6)
October, 2011 (14)
September, 2011 (5)
August, 2011 (3)
June, 2011 (2)
May, 2011 (1)
April, 2011 (3)
March, 2011 (6)
February, 2011 (3)
January, 2011 (6)
December, 2010 (3)
November, 2010 (8)
October, 2010 (6)
September, 2010 (6)
August, 2010 (7)
July, 2010 (8)
June, 2010 (6)
May, 2010 (8)
April, 2010 (13)
March, 2010 (7)
February, 2010 (5)
January, 2010 (9)
December, 2009 (6)
November, 2009 (8)
October, 2009 (11)
September, 2009 (5)
August, 2009 (5)
July, 2009 (10)
June, 2009 (5)
May, 2009 (7)
April, 2009 (7)
March, 2009 (11)
February, 2009 (6)
January, 2009 (9)
December, 2008 (5)
November, 2008 (4)
October, 2008 (7)
September, 2008 (8)
August, 2008 (11)
July, 2008 (11)
June, 2008 (10)
May, 2008 (6)
April, 2008 (8)
March, 2008 (9)
February, 2008 (6)
January, 2008 (6)
December, 2007 (6)
November, 2007 (9)
October, 2007 (7)
September, 2007 (5)
August, 2007 (8)
July, 2007 (6)
June, 2007 (8)
May, 2007 (7)
April, 2007 (9)
March, 2007 (8)
February, 2007 (5)
January, 2007 (9)
December, 2006 (4)
November, 2006 (3)
October, 2006 (4)
September, 2006 (9)
August, 2006 (4)
July, 2006 (9)
June, 2006 (4)
May, 2006 (10)
April, 2006 (4)
March, 2006 (11)
February, 2006 (3)
January, 2006 (13)
December, 2005 (6)
November, 2005 (7)
October, 2005 (4)
September, 2005 (9)
August, 2005 (6)
July, 2005 (7)
June, 2005 (5)
May, 2005 (4)
April, 2005 (7)
March, 2005 (16)
February, 2005 (17)
January, 2005 (17)
December, 2004 (13)
November, 2004 (7)
October, 2004 (14)
September, 2004 (11)
August, 2004 (7)
July, 2004 (3)
June, 2004 (6)
May, 2004 (3)
April, 2004 (2)
March, 2004 (1)
February, 2004 (5)
Categories
About

Powered by: newtelligence dasBlog 2.0.7226.0

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2017, Marimer LLC

Send mail to the author(s) E-mail



Sign In