Debugging Dependency Properties in WPF: Addendum

Posted by: Clarity Blogs: ASP.NET, on 23 Jan 2009 | View original | Bookmarked: 0 time(s)

This is going to be a pretty brief post. I just wanted to mention a small addition to the data binding debugging solution I posted about last time. When we left off, we had a pretty decent solution to debugging via a property changed callback. And here it is:

   1:  public static PropertyChangedCallback PrintfDebugger
   2:      (PropertyChangedCallback propertyChangedCallback)
   3:  {
   4:      return (d, e) =>
   5:      {
   6:          propertyChangedCallback(d, e);
   7:          Console.WriteLine("{0}.{1}: {2}",
   8:              d.DependencyObjectType.Name,
   9:              e.Property.Name,
  10:              e.NewValue);
  11:      };
  12:  }

This works fine, but it's slightly limited. One common scenario where this might not be so useful is if you have several of the same type of control on the same page. This would make it pretty difficult to tell which control is actually receiving the update. What can we do? Well, we can mitigate this by using the name of the element, if it exists.

   1:  public static PropertyChangedCallback PrintfDebugger
   2:      (PropertyChangedCallback propertyChangedCallback)
   3:  {
   4:      return (d, e) =>
   5:      {
   6:          propertyChangedCallback(d, e);
   7:          var elem = d as FrameworkElement;
   8:          string name = elem != null && !string.IsNullOrEmpty(elem.Name) ? 
   9:              elem.Name : 
  10:              d.DependencyObjectType.Name;
  11:          Console.WriteLine("{0}.{1}: {2}",
  12:              name,
  13:              e.Property.Name,
  14:              e.NewValue);
  15:      };
  16:  }

Here we check to see if the dependency object is a FrameworkElement. If it is, and it has a name, we use that. Otherwise, we default to the class name. Note that there are other classes that implement a Name property, but, for the sake of simplicity, I've restricted this to what I believe is the most common scenario. Now, let's see it in action. First, we'll confirm that it still works in our previous case by leaving the control unnamed, like so:

   1:  <Grid>
   2:      <local:MyUserControl MyProperty="{Binding ActualWidth, ElementName=root}"/>
   3:  </Grid>

And running it yields the desired result:

image

Now, let's add a second named control with the same binding.

   1:  <Grid>
   2:      <local:MyUserControl MyProperty="{Binding ActualWidth, ElementName=root}"/>
   3:      <local:MyUserControl x:Name="newControl" MyProperty="{Binding ActualWidth, ElementName=root}"/>
   4:  </Grid>

And the moment of truth:

image

Nice.

Advertisement
Free Agile Project Management Tool from Telerik
TeamPulse Community Edition helps your team effectively capture requirements, manage project plans, assign and track work, and most importantly, be continually connected with each other.
Category: Debugger | Other Posts: View all posts by this blogger | Report as irrelevant | View bloggers stats | Views: 1 | Hits: 0

News Categories

.NET | Agile | Ajax | Architecture | ASP.NET | BizTalk | C# | Certification | Data | DataGrid | DataSet | Debugger | DotNetNuke | Events | GridView | IIS | Indigo | JavaScript | Mobile | Mono | Patterns and Practices | Performance | Podcast | Refactor | Regex | Security | Sharepoint | Silverlight | Smart Client Applications | Software | SQL | VB.NET | Visual Studio | W3 | WCF | WinFx | WPF | WSE | XAML | XLinq | XML | XSD