WPF绑定(bind): How to avoid "property not found" runtime errors at design time

标签 wpf testing

我想以某种方式确保 xaml 中的所有绑定(bind)都绑定(bind)到现有属性。

我想避免像这样的运行时错误:

BindingExpression path error: 'Fullname' property not found on 'object' ''Person' (HashCode=33132859)'. 
BindingExpression:Path=Person.Fullname; DataItem='ViewModel' (HashCode=46007650); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

每个 View 都使用 d:DesignInstance 指定数据上下文类型,并且每个 DataTemplate 如果无法从上下文继承(例如 ListBoxItem 模板),则使用 DataType 属性。

在 Visual Studio Xaml 设计器中,无效属性带有下划线,并且在运行时我在输出窗口中收到绑定(bind)错误。

有没有任何工具可以检查这些错误?我正在考虑一些自动化的 UI 测试,它会遍历整个应用程序并检查调试输出,但设置起来非常困难。

如果 resharper 可以解析 xaml 并识别无效绑定(bind),至少理论上应该可以在代码分析或单元测试中做到这一点。

编辑: 我已向 uservoice 添加了建议:https://wpf.uservoice.com/forums/40688-general/suggestions/7423474-strongly-typed-binding-testability 请投票!

最佳答案

我喜欢这个解决方案: https://web.archive.org/web/20130505005640/http://tech.pro/tutorial/940/wpf-snippet-detecting-binding-errors 。 每次绑定(bind)失败时,您都会收到一条弹出消息。

编辑:根据要求,这里是 BindingErrorTraceListener 的源代码,由 Michael Kuehl 编写。 ,包括 Jesse Chisholm 的错误修复(通过 Dispatcher 将 MessageBox 发送到 GUI 线程)。

using System.Diagnostics;
using System.Text;
using System.Windows;

namespace SOTC_BindingErrorTracer
{
  public class BindingErrorTraceListener : DefaultTraceListener
  {
    private static BindingErrorTraceListener _Listener;

    public static void SetTrace()
    { SetTrace(SourceLevels.Error, TraceOptions.None); }

    public static void SetTrace(SourceLevels level, TraceOptions options)
    {
      if (_Listener == null)
      {
        _Listener = new BindingErrorTraceListener();
        PresentationTraceSources.DataBindingSource.Listeners.Add(_Listener);
      }

      _Listener.TraceOutputOptions = options;
      PresentationTraceSources.DataBindingSource.Switch.Level = level;
    }

    public static void CloseTrace()
    {
      if (_Listener == null)
      { return; }

      _Listener.Flush();
      _Listener.Close();
      PresentationTraceSources.DataBindingSource.Listeners.Remove(_Listener);
      _Listener = null;
    }



    private StringBuilder _Message = new StringBuilder();

    private BindingErrorTraceListener()
    { }

    public override void Write(string message)
    { _Message.Append(message); }

    public override void WriteLine(string message)
    {
      _Message.Append(message);

      var final = _Message.ToString();
      _Message.Length = 0;

      Application.Current.Dispatcher.BeginInvoke(
          System.Windows.Threading.DispatcherPriority.Normal, 
          new System.Windows.Threading.DispatcherOperationCallback(delegate { MessageBox.Show(final, "Binding Error", MessageBoxButton.OK, 
        MessageBoxImage.Error); return null; }), 
          null);
    }
  }
}

然后,在您的 Window 或 View 基类中,添加以下行

BindingErrorTraceListener.SetTrace();

打开弹出窗口。

关于WPF绑定(bind): How to avoid "property not found" runtime errors at design time,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29365462/

相关文章:

java - 如果无法验证,如何检查测试用例

unit-testing - 使用 pytest 测试 Flask 应用程序时找不到 404

ios - 在 iOS 上使用 UI 自动化测试屏幕跟踪

ruby-on-rails - 如何在 Rails 中运行测试时保留数据

language-agnostic - 您是否曾经更改过代码而只是进行测试,而不是试图完全理解您所做的更改?

wpf - WPF Datagrid 控件能否在列布局方面表现得像 WinForms DataGridControl?

c# - 关闭事件中的 ShowDialog

c# - C#中跨类的静态变量初始化顺序是什么?

c# - 应用程序启动时出现 ValidationError XamlParseException

c# - 编辑 XAML 导致 Visual Studio 的设计器崩溃