Monthly Archives: August 2010

Listening to DependencyProperty changes in Silverlight

The dependency property system is a pretty nice concept. Receiving notifications for dependency property changes on an existing object is a very common scenario in order to update my view model or the UI.

This is quite easy in WPF:

// get the property descriptor
DependencyPropertyDescriptor prop = 
         DependencyPropertyDescriptor.FromProperty(TextBox.TextProperty, myTextBox.GetType());
// add change handler
prop.AddValueChanged(myTextBox, (sender, args) =>
{

});

Unfortunately Silverlight has a limited set of meta-data functionality around the dependency property system, because the DependencyPropertyDescriptor does exist in Silverlight.

In order to get a workaround I found a solution in which I get notified with help of the binding system. I simple use a relay object which value property is bound to the source property I want to get notified. The relay object contains a public event which raises when the value changes.

image

 

I’ve put the implementation details into a DependencyPropertyChangedListener class to make it as simple as possible and similar to WPF. The lines below show how simple it is to create the listener and attaching the event.

private DependencyPropertyChangedListener listener;
       
public MainPage()
{
    InitializeComponent();

    listener = DependencyPropertyChangedListener.Create(this.myTextBox, "Text");
    listener.ValueChanged += listener_ValueChanged;
}

void listener_ValueChanged(object sender, DependencyPropertyValueChangedEventArgs e)
{
    Debug.WriteLine(e.OldValue + " " + e.NewValue);
}

private void btnSetValue_Click(object sender, RoutedEventArgs e)
{
    this.myTextBox.Text = DateTime.Now.Ticks.ToString();
}

The listener provides the method Detach to release the binding.

listener.Detach();

 

Known Limitations

It is not possible to listen for dependency property values which are inherited like the FontSize, DataContext and FontFamily properties so far.

 

Source code

image

Here you can find a demo project with full source code.

 

Keywords: Registering to a Dependency Property Change Event Property OverrideMetadata PropertyDescriptor prop TypeDescriptor GetProperties Receive notifications for dependency properties

Advertisements
Tagged

.NET Reflector – Working with different profiles for Silverlight and the Core Framework

.NET Reflector is a one of the 10 Must-Have utilities for .NET developers. If you need to work with more than one version of the .NET Framework, especially with Silverlight and the Core Framework (3.5 or 4.0) you will find you reconfiguring your Reflector every time you changing the platform. For me this is very annoying tasks for which I was looking for a solution.

 

Different config files

.NET Reflector stores it settings into a config structure which includes all assemblies from the left tree in the application.

Recently I noticed the ability to start .NET Reflector with command line arguments. One command line argument allows to specify a config file path:
"C:\Program Files\Reflector\Reflector.exe" /configuration:”Reflector.cfg”

Unfortunately there seems to be a bug in version 6.1.0.11. When closing Reflector it reports the following error:

clip_image001

When changing the config-path to an absolute syntax then it works fine:
"C:\Program Files\Reflector\Reflector.exe" /configuration:”C:\Program Files\Reflector\Reflector.cfg”

Creating different profiles

First create different .NET Reflector shortcuts for each profile you want to have. In my case these are Silverlight, .NET 3.5 and .NET 4.0.

clip_image002

Edit every shortcut and add the /configuration argument to every shortcut with a different name as config file. The config file must not exists at this time.

My shortcuts are as following:

  • "C:\Program Files\Reflector\Reflector.exe" /configuration:"C:\Program Files\Reflector\DOTNET40.cfg"
  • "C:\Program Files\Reflector\Reflector.exe" /configuration:"C:\Program Files\Reflector\DOTNET35.cfg"
  • "C:\Program Files\Reflector\Reflector.exe" /configuration:"C:\Program Files\Reflector\Silverlight.cfg"

clip_image003

Now start each profile with its shortcut. .NET Reflector will not find a config and asks you which default assembly list you want to use. Select the version matching to your shortcut and repeat this for every shortcut you have created.

clip_image004

 

Existing Add-Ins

.NET Reflector has a clear and simple config file structure. Therefore you can easily copy and paste your favorite Add-Ins from one config file to another config file.

image

 

Improving startup

Working with Vista/Windows 7 makes it very easy to find programs via the start menu. To use the program search, just put a copy of your shortcuts into your start menu folder (or a subfolder in it).

C:\ProgramData\Microsoft\Windows\Start Menu\Programs\MyStartMenuLinks

image

Now you can type in “Reflector” into your start menu search box and you get a selection of different .NET Reflector profiles.

clip_image007

For me these profiles are very helpful during my daily coding life.

Tagged , ,

VS 2010 Unit Test Problem with DataSet and Remoting

We ran into problems when using Visual Studio 2010 Unit Tests targeting Framework 3.5.

We use Visual Studio 2010 for our development, but we still use .NET Framework 3.5, because our customers a not ready to run .NET 4.0 applications.

Problem description in detail

When trying to transfer a DataSet instance over .NET Remoting and the executing client is a unit test environment, then it fails with an exception: “AssemblyResolveException…System.Data 4.0.0.0 not found…”

.NET Remoting uses the XmlSerializer to serialize and deserialize DataSets over Remoting boundaries.
The XmlSerializer itself generates a dynamic in-memory assembly for each root-type in the object graph it serializes. This assembly is used to serialize or deserialize the object graph. That means initially the XmlSerializer creates a dynamic assembly with a reference to System.Data 4.0.0.0, because Visual Studio 2010 executes its Unit Tests with the runtime 4.0.

On server side .NET Remoting is trying to deserialize the DataSet of Version 4.0.0.0 (because of the System.Data 4.0.0.0 reference on client side). The deserialization process fails, because the server is running with Framework version 3.5.
Unfortunately VS2010 does not allow setting another Framework version for unit test projects, only version 4.0 is supported (http://connect.microsoft.com/VisualStudio/feedback/details/483939/unable-to-change-target-framework-version-on-unit-test-projects).

Possible solutions so far

  1. Migrate client and server to .NET 4.0
  2. Run unit tests with VS 2008
  3. Implement the AssemblyResolve event on server side and redirect to the System.Data 3.5.0.0
  4. Add an assemblyBinding element to the server’s config file to redirect System.Data 4.0.0.0 to System.Data 3.5.0.0
  5. Waiting for a new Visual Studio Version which supports different target frameworks for unit test projects.

Our solution

We use the assemblyBinding element to redirect the System.Data 4.0.0.0 assembly request to System.Data 3.5.0.0. If we put the following config section into our application server app.config then we are able to use VS2010 for our Unit Tests targeting Framework 3.5.

<runtime>
   <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
          <assemblyIdentity name="System.Data" publicKeyToken="b77a5c561934e089"/>
          <bindingRedirect oldVersion="4.0.0.0" newVersion="2.0.0.0"/>
        </dependentAssembly>
   </assemblyBinding>
</runtime>  

 

Resources

Tagged ,