Как обнаружить сломанную привязку данных WPF?
при попытке ответить на вопрос, в непосредственной близости 'модульное тестирование Привязок WPF у меня следующий мучительный вопрос..
каков наилучший способ найти, если у вас неправильная настройка проводки привязки данных WPF (или вы просто сломали что-то, что было подключено правильно) ?
хотя подход модульного тестирования, похоже, похож на Джоэла, "отрывающего руку, чтобы удалить занозу".. Я ищу более простые и менее накладные способы обнаружения этот.
все, похоже, взяли на себя обязательства по привязке данных с помощью WPF.. и в этом есть свои достоинства.
7 ответов
в .NET 3.5 был введен новый способ вывода информации трассировки о конкретных привязках данных.
Это делается через новый
лучшее, что я смог найти...
как я могу отлаживать привязки WPF? по Беатрис Stollnitz
поскольку все не могут всегда следить за окном вывода, ища ошибки привязки, мне понравился вариант № 2. Что добавить это в приложение.Config
<?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.Запустите Service Trace Viewer с помощью окна команд для перехода к Расположение установки WCF (C:\Program Файлы\Microsoft Пакет SDK папке\Windows\V6 двигателем.0\Бин), а затем введите SvcTraceViewer.исполняемый. (хотя мы нашли наши в \v7.0\Bin)
Примечание: средство просмотра трассировки службы может связываться с двумя типами файлов: .svclog и .stvproj все. Вы можете использовать два параметры в командной строке для регистрации и отмените регистрацию расширений файлов.
/ register: Регистрация ассоциации расширение файла." svclog ПО" и ".stvproj " с SvcTraceViewer.exe
/unregister: отменить регистрацию ассоциации файла увеличение ".svclog "and".stvproj " с SvcTraceViewer.exe
1.При запуске Service Trace Viewer щелкните файл и выберите пункт Открыть. Перейдите к местоположению, где файлы трассировки сохраняются.
2.Дважды щелкните файл трассировки, который требуется открыть.
Примечание: нажмите SHIFT при нажатии несколько файлов трассировки для выбора и откройте их одновременно. Услуга Trace Viewer объединяет содержимое всех файлы и представляет один вид. Для например, можно открыть файлы трассировки и клиент и обслуживание. Это полезно при включении сообщения ведение журнала и распространение активности в конфигурация. Таким образом, вы можете изучить обмен сообщениями между клиент и обслуживание. Вы также можете перетащить несколько файлов во вьювер или использование вкладка проект. См управление Раздел проекта для более подробной информации.
3.Чтобы добавить дополнительные файлы трассировки в открытую коллекцию, щелкните файл а затем Добавлять. В окне откроется, перейдите к местоположению файлов трассировки и дважды щелкните файл, который вы хотите добавить.
кроме того, что касается фильтрации файла журнала, мы нашли эту ссылку чрезвычайно полезной:
для тех, кто, как я, ищет чистый программный способ включения всей трассировки 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;
}
}
}