Подтвердить что ты не робот

Как найти источник ошибки привязки?

Как я могу выяснить, какая строка xaml содержит трудную привязку. Когда мой вывод отладки полон строк, таких как:

System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='UW.Entities.ProgramModel.UWProgram' BindingExpression:Path=; DataItem='RuntimeType' (HashCode=24995901); target element is 'DataGridCollectionViewSource' (HashCode=60976864); target property is 'Source' (type 'Object')

Я не знаю, как интерпретировать это так, чтобы я мог найти ответственную строку xaml. Я даже не могу понять, из какого файла xaml возникает ошибка. Есть ли способ получить дополнительную информацию при возникновении этих ошибок?

'UW.Entities.ProgramModel.UWProgram' - это всего лишь тип - я не знаю, к чему привязан объект. У меня также есть много DataGridCollectionViewSources в разных битах xaml, все, у кого свойство "Источник" связано с чем-то, что может иметь или не иметь этот тип (опять же - нелегкий способ сказать).

4b9b3361

Ответ 1

Если вы не знаете, какая привязка завершается неудачно

Для этой цели я использовал утилиту Snoop. Короче - в верхнем левом углу над визуальным деревом вы найдете раскрывающийся список, который позволяет фильтровать визуальные эффекты, просто выберите Visuals с привязкой Error. Подробнее см. онлайн-документацию.

Если вы знаете, какая привязка не работает

Когда-нибудь вы знаете, какая привязка не удалась, но не смог найти источник проблемы, поскольку привязка довольно сложная, например, TemplateBindings, привязки, которые относятся к DataContext другого элемента управления и т.д. Я нашел полезным положить a TextBlock какое свойство Text привязано к одному и тому же источнику привязки таким образом, вы можете видеть, что именно связано, поскольку TextBlock будет отображать имя типа связанного объекта.

Например, у вас есть неудачное связывание:

<ItemsControl ItemsSource="{Binding Parent.DataContext.ActiveItem.DataContext}" />

<!-- See what is bound, if failed - try previous level  -->
<TextBlock Text="{Binding Parent.DataContext}" />
<TextBlock Text="{Binding Parent.Inner.Items}" />
<TextBlock Text="{Binding Parent.Inner}" />

Полезные ссылки:

Ответ 2

Я с удовольствием воспользовался замечательным фрагментом из "Switch the Code", чтобы обнаружить и сообщить о ошибках привязки, поскольку он был впервые опубликован в 2009 году...

http://www.switchonthecode.com/tutorials/wpf-snippet-detecting-binding-errors

edit: по-прежнему отлично работает на VS2012 (сентябрь 2013 г.)

Обновление 25 января 2016 г.

Ссылка отображается сломанной, поэтому я вставляю соответствующие фрагменты...

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

namespace SOTC_BindingErrorTracer
{
    public class BindingErrorTraceListener : DefaultTraceListener
    {   //http://www.switchonthecode.com/tutorials/wpf-snippet-detecting-binding-errors
        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;

            MessageBox.Show(final, "Binding Error", MessageBoxButton.OK,
              MessageBoxImage.Error);
        }
    }
}

И настроить его/инициализировать...

namespace WpfListeningForTraceErrors
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            BindingErrorTraceListener.SetTrace();
            InitializeComponent();
        }
    }
}

Ответ 3

Вы можете добавить это к каждому элементу управления, который связывает

  PresentationTraceSources.TraceLevel="High" 

И запустите программу в отладочном режиме, подробная информация о привязке появится в окне вывода. Это может немного помочь. Вы также можете создать проход через конвертер, чтобы поймать ошибку (улавливает проблему несколько раз, но не всегда). Нет никаких хороших инструментов для отладки XAML в целом, о которой я знаю.

Ответ 4

Вы можете загрузить инструмент Snoop, который позволит вам отлаживать привязки. Это дает представление о визуальном дереве приложений WPF, позволяющем выявлять любые ошибки привязки, которые он находит.

Вы можете получить базовую информацию об ошибках привязки в окне вывода в Visual Studio. Он покажет ошибку пути выражения привязки и строку, в которой произошла ошибка.

Ответ 5

В VisualStudio перейдите в Tools-> Расширения и Updates-> (скачать Output Enhancer). Когда вы создаете свое решение, вы получите точный вид сообщения об ошибке, которое вы разместили красным цветом, если есть ошибка привязки.

Output enhancer