Как обнаружить нарушенную привязку данных WPF?
при попытке ответить на вопрос, в непосредственной близости ' модульное тестирование Привязок WPF
7 ответов:
в .NET 3.5 был введен новый способ специально выводить информацию трассировки о конкретных привязках данных.
Это делается через новый
лучшее, что я смог найти...
как я могу отлаживать привязки WPF? Беатрис Штольниц
поскольку все не всегда могут следить за окном вывода, ища ошибки привязки, мне понравился вариант № 2. То есть добавить это в свое приложение.Конфигурации
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <sources> <source name="System.Windows.Data" switchName="SourceSwitch" > <listeners> <add name="textListener" /> </listeners> </source> </sources> <switches> <add name="SourceSwitch" value="All" /> </switches> <sharedListeners> <add name="textListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="GraveOfBindErrors.txt" /> </sharedListeners> <trace autoflush="true" indentsize="4"></trace> </system.diagnostics> </configuration>
соедините это с хорошим сценарием сканирования регулярных выражений, чтобы извлечь соответствующую информацию, которую вы можете иногда запускать на GraveOfBindErrors.txt в папке выходных данных
System.Windows.Data Error: 35 : BindingExpression path error: 'MyProperty' property not found on 'object' ''MyWindow' (Name='')'. BindingExpression:Path=MyProperty; DataItem='MyWindow' (Name=''); target element is 'TextBox' (Name='txtValue2'); target property is 'Text' (type 'String')
вы можете использовать функцию отладки триггера инспектора WPF. Просто загрузите инструмент из codeplex и прикрепите его к запущенному приложению. Это также показывает ошибки привязки в нижней части окна. Очень полезный инструмент!
Я использую решение, представленное здесь, чтобы превратить ошибки привязки в собственные исключения: http://www.jasonbock.net/jb/Default.aspx?blog=entry.0f221e047de740ee90722b248933a28d
однако обычный сценарий в привязках WPF заключается в создании исключений в случае, если пользовательский ввод не может быть преобразован в целевой тип (например, текстовое поле, привязанное к целочисленному полю; ввод нечисловой строки приводит к FormatException, вводу числа, которое является слишком большим результатом в OverflowException). Аналогичный случай имеет место, когда сеттер исходного свойства создает исключение.
способ обработки WPF это с помощью ValidatesOnExceptions=true и ValidationExceptionRule, чтобы сигнализировать пользователю, что предоставленный вход неверен (используя сообщение об исключении).
однако эти исключения также отправляются в окно вывода и, таким образом, "ловятся" BindingListener, что приводит к ошибке...явно не то поведение, которое вы бы хотеть.
поэтому я расширил
BindingListener
класс, чтобы не бросать исключение в этих случаях:private static readonly IList<string> m_MessagesToIgnore = new List<String>() { //Windows.Data.Error 7 //Binding transfer from target to source failed because of an exception //Normal WPF Scenario, requires ValidatesOnExceptions / ExceptionValidationRule //To cope with these kind of errors "ConvertBack cannot convert value", //Windows.Data.Error 8 //Binding transfer from target to source failed because of an exception //Normal WPF Scenario, requires ValidatesOnExceptions / ExceptionValidationRule //To cope with these kind of errors "Cannot save value from target back to source" };
измененные строки в public override void WriteLine (строковое сообщение):
.... if (this.InformationPropertyCount == 0) { //Only treat message as an exception if it is not to be ignored if (!m_MessagesToIgnore.Any( x => this.Message.StartsWith(x, StringComparison.InvariantCultureIgnoreCase))) { PresentationTraceSources.DataBindingSource.Listeners.Remove(this); throw new BindingException(this.Message, new BindingExceptionInformation(this.Callstack, System.DateTime.Parse(this.DateTime), this.LogicalOperationStack, int.Parse(this.ProcessId), int.Parse(this.ThreadId), long.Parse(this.Timestamp))); } else { //Ignore message, reset values this.IsFirstWrite = true; this.DetermineInformationPropertyCount(); } } }
вот полезный метод для отладки / трассировки триггеров эффективно. Она позволяет вести журнал всех действий с элементом воздействия:
http://www.wpfmentor.com/2009/01/how-to-debug-triggers-using-trigger.html
Это было очень полезно для нас, но я хотел добавить к тем, кто считает это полезным, что есть утилита, которую Microsoft предоставляет с sdk для чтения этого файла.
найдено здесь:http://msdn.microsoft.com/en-us/library/ms732023.aspx
открыть файл трассировки
1.Запустите Средство просмотра трассировки службы с помощью командного окна для перехода к нужному Место установки WCF (C:\Program Файлы\Microsoft SDKs\Windows\v6. 0\Bin), а затем введите SvcTraceViewer.исполняемый. (хотя мы нашли наш в \v7. 0 \ Bin)
Примечание: средство просмотра трассировки службы можно связать с двумя типами файлов : .svclog и .stvproj все. Вы можете использовать два параметры в командной строке для регистрации и отмените регистрацию расширений файлов.
/ register: зарегистрировать ассоциацию расширение файла." svclog ПО" и ".stvproj " с SvcTraceViewer.exe
/unregister: отменить регистрацию ассоциация файлов увеличение ".svclog ПО" и ".stvproj " с SvcTraceViewer.exe
1.При запуске средства просмотра трассировки служб щелкните файл и выберите пункт Открыть. Перейдите к месту, где ваш файлы трассировки сохраняются.
2.Дважды щелкните файл трассировки, который требуется открыть.
Примечание: нажмите SHIFT при нажатии несколько файлов трассировки для выбора и откройте их одновременно. Услуга Средство просмотра трассировки объединяет содержимое всех файлы и представляет один вид. Для например, вы можете открыть файлы трассировки как клиент, так и сервис. Это полезно, когда вы включили сообщение ведение журнала и распространение активности в конфигурация. Таким образом, вы можете проверьте обмен сообщениями между клиент и обслуживание. Вы также можете перетащить несколько файлов в средстве просмотра, или использовать вкладка проект. См. раздел Управление Раздел проекта для получения более подробной информации.
3.To добавьте дополнительные файлы трассировки в открытую коллекцию, щелкните файл а затем Добавлять. В окне что откроется, перейдите к местоположению файлов трассировки и дважды щелкните файл, который вы хотите добавить.
кроме того, что касается фильтрации файла журнала, мы нашли эту ссылку чрезвычайно полезной:
для тех, кто, как я, ищет чистый программный способ включения всей трассировки WPF на заданном уровне трассировки, вот фрагмент кода, который это делает. Для справки, он основан на этой статье:источники трассировки в WPF.
это не требует изменения в приложение.конфигурационный файл, и он также не требует изменения реестра.
Это, как я использую его, в каком-то месте запуска (приложение, и т. д.):
.... #if DEBUG WpfUtilities.SetTracing(); #endif ....
а вот код утилиты (by по умолчанию он отправляет все предупреждения Прослушивателю трассировки по умолчанию):
public static void SetTracing() { SetTracing(SourceLevels.Warning, null); } public static void SetTracing(SourceLevels levels, TraceListener listener) { if (listener == null) { listener = new DefaultTraceListener(); } // enable WPF tracing PresentationTraceSources.Refresh(); // enable all WPF Trace sources (change this if you only want DataBindingSource) foreach (PropertyInfo pi in typeof(PresentationTraceSources).GetProperties(BindingFlags.Static | BindingFlags.Public)) { if (typeof(TraceSource).IsAssignableFrom(pi.PropertyType)) { TraceSource ts = (TraceSource)pi.GetValue(null, null); ts.Listeners.Add(listener); ts.Switch.Level = levels; } } }