官术网_书友最值得收藏!

Exploiting converters

If we're having a problem with a data binding that uses an IValueConverter to convert the data bound value from one type to another, then we can place a breakpoint into the Convert method of the converter. As long as we have correctly set up the converter, we can be sure that the breakpoint will be hit when the binding is evaluated at runtime. If it doesn't get hit, that will mean that we have not set it up correctly.

However, even when we are not already using a converter on a binding that is not displaying the value that we are expecting, we can still add one just for this purpose. We can either add an existing converter to the binding, if we have one of the relevant type, or we can create a simple converter specifically for the purpose of debugging and use that instead. Let's take a look at how we might do this:

[ValueConversion(typeof(object), typeof(object))] 
public class DebugConverter : IValueConverter 
{ 
  public object Convert(object value, Type targetType, object parameter,
CultureInfo culture) { if (Debugger.IsAttached) Debugger.Break(); return value; } public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture) { if (Debugger.IsAttached) Debugger.Break(); return value; } }

As you can see from the preceding code snippet, it's a very simple implementation of the IValueConverter interface. We start by specifying that we are converting from object to object in the ValueConversion attribute, thereby outlining that we are not actually converting any data bound values in this converter. The rest of the class represents a typical converter class, but without any conversion code.

The only real point of interest here are the two calls to the Debugger.Break method from the System.Diagnostics assembly. When the program execution reaches either of these method calls, it will automatically break, just as if there were breakpoints set on these lines. Therefore, when using this converter, we don't even need to set breakpoints; we can just plug it into the binding, run the program, and investigate the value of the value input parameter.

It can be attached like any other converter:

xmlns:Converters="clr-namespace:CompanyName.ApplicationName.Converters; 
  assembly=CompanyName.ApplicationName.Converters" 
... 
<UserControl.Resources> 
  <Converters:DebugConverter x:Key="Debug" /> 
</UserControl.Resources> 
... 
<ListBox ItemsSource="{Binding Items, Converter={StaticResource Debug}}" />

However, this method can be unsafe to use in a production environment and the converter should be removed when debugging is finished. If it is left connected in release code, an Exception will be thrown at runtime, complaining that Windows has encountered a user-defined breakpoint. Although I wouldn't recommend leaving a converter that is just used for debugging data bound values connected in a production environment, we can make a slight alteration to it to completely eliminate the danger of this occurring:

[ValueConversion(typeof(object), typeof(object))] 
public class DebugConverter : IValueConverter 
{ 
  public object Convert(object value, Type targetType, object parameter,
CultureInfo culture) { Break(value); return value; } public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture) { Break(value); return value; }

[Conditional("DEBUG")]
private void Break(object value)
{
Debugger.Break();
}
}

Now, the Debugger.Break method and the data bound value have been moved into a separate Break method, where the value of the value input parameter can be inspected. Note the use of the ConditionalAttribute attribute on this new method. It provides a way to include or exclude methods that it has been set on, depending on the current solution configuration. If the configuration is set to debug, this method can be called, but otherwise, all calls to it are removed from the compiled code. In this way, we can be assured that we will not run into problems with our release code.

主站蜘蛛池模板: 腾冲县| 芜湖市| 张家界市| 札达县| 成武县| 闸北区| 崇信县| 通山县| 佛学| 定边县| 闽清县| 陆良县| 高邮市| 梁河县| 通化县| 鸡西市| 鸡东县| 拉萨市| 肃宁县| 苗栗市| 永清县| 张北县| 喀喇沁旗| 景德镇市| 海阳市| 赣州市| 阿瓦提县| 丹东市| 康保县| 简阳市| 大竹县| 宣恩县| 玛沁县| 雅安市| 高密市| 吉木萨尔县| 桦川县| 甘孜县| 通化县| 麻江县| 忻州市|