Проверка привязки данных в XAML во время компиляции
Im работает над приложением на основе WPF. Среда - VS2008 SP1 с .NET 3.5 SP 1.
В нашем развитии мы широко используем шаблон MVVM.
т.е. разработчики приложений пишут Модели и ViewModels (С#), тогда разработчики пользовательского интерфейса будут писать "Представления" с помощью WPF Binding (XAML). Разработчики приложений также записывают единичные тесты поверх ViewModels.
Мы используем методологию непрерывной интеграции, и мы создаем diond и выполняем unit test для каждой модификации
Проблема заключается в отсутствии процесса или инструментов проверки правильности привязки данных в XAML.
Например:
- Разработчик приложений пишет свойство NmberOfApples и модульные тесты, чтобы проверить его правильное поведение.
- Разработчик пользовательского интерфейса создает пользовательский контроль и привязывает его к свойству
- Разработчик приложения обнаруживает, что свойство имеет орфографию и исправляет ее имя до NumberOfApples
- Ошибки времени компиляции в любом коде С# используют свойство NmberOfApples, и такие ошибки будут легко улавливаться (непрерывная интеграция)
- Связывание данных в файлах XAML не будет проверяться, и это будет ошибка времени выполнения.
Мой вопрос будет: "Есть ли какой-либо инструмент или методология, которые помогают нам проверять правильность привязки данных в XAML во время компиляции?"
Ответы
Ответ 1
Решение вашей проблемы обсуждается в этой статье .
Основная идея состоит в том, чтобы создать набор статических (С#) классов ViewModel MetaData, которые содержат строковое значение свойств ваших классов ViewModel, которые затем можно использовать в вашем xaml. В статье объясняется, как использовать генерацию текста T4 для создания этих статических классов метаданных. Вы можете использовать любой инструмент генерации кода по своему усмотрению.
поэтому ваша виртуальная машина имеет следующее:
namespace Mine
{
public class MyViewModel
{
public int MyInt {get;set;}
public string MyString {get;set;}
}
}
И генерация кода создала бы это:
namespace Mine.MetaData
{
public static class MyViewModelMetaData
{
public const string MyInt = "MyInt";
public const string MyString = "MyString";
}
}
а затем в вашем xaml вы добавите пространство имен в свой xaml и привяжите свои элементы управления к классу метаданных
<TextBox Text="{Binding Path={x:Static Metadata:MyViewModelMetadata.MyInt}}"/>
Если вы используете надстройку типа resharper, то она даст вам intellisense свойства класса static, а также потому, что вы ссылаются на точное свойство в статическом классе, когда статический класс восстанавливается, ваш xaml не должен компилироваться.
Это довольно скользкий, я думаю, что это потрясающе, и у него есть шанс удержать большинство людей в здравом уме, но ваш пробег может измениться.:)
EDIT:
Кстати, я не покупаю "ViewModels тесно связаны с представлениями". По моему мнению, Views неразрывно связаны с их ViewModels, но это должен быть только один путь. ViewModels должны быть полностью независимы от любой реализации представления. Это похоже на ViewModel - это интерфейс, а представление - это конкретный реализованный класс. Поэтому по этой причине я не добавляю никаких свойств WPF (например, перечисление видимости) в свой ViewModel, потому что это связывает меня с WPF на вечность (что не очень плохо:)), но это компрометирует обслуживание.
Ответ 2
Если вы установите ReSharper, одна из (многих) функций, которые вы получите, это "проверка кода". Одна из вещей, которые обнаружит этот осмотр, - это случаи, когда ваша привязка не разрешает свойство в контексте данных. Вы можете легко отфильтровать окно "Результаты проверки", чтобы отображать только эти проблемы.
Обратите внимание, что вы должны явно указать тип вашей модели представления в своих ресурсах XAML, чтобы это работало.
![Example of ReSharper inspections]()
Ответ 3
Существует несколько возможных сценариев, когда это поведение действительно необходимо. В любом случае, по дизайну, ошибки привязки привязаны и являются причиной, по которой у вас возникнут проблемы с поиском чего-либо, что поможет вам в этом.
Лучшее, что я видел, это обработчик проверки исключения, который отображает ошибки привязки:
http://msdn.microsoft.com/en-us/library/system.windows.controls.exceptionvalidationrule.aspx
Аргумент для этого - представления, а ViewModels предназначены для развязки до точки, где View может использоваться для нескольких ViewModels. Он также помогает в "изгибаемости" представлений, так что теоретически дизайнерские типы могут создавать представление, не запуская кучу ошибок, пока они это делают. Я понимаю, что это может не соответствовать вашему процессу, но эта история.
Ответ 4
Прошли годы с тех пор, как был задан исходный вопрос и ответили, но, как я только что проверял, с тех пор решение могло стать проще. ReSharper, кажется, предлагает правильный Intellisense без необходимости генерации статических классов, упомянутых в принятом ответе.
Но я не был свидетелем ошибки времени компиляции, как указано в принятом ответе. Я даже пытался использовать [XamlCompilation (XamlCompilationOptions.Compile)] безрезультатно. Пожалуйста, поддержите меня, если я что-то упустил.
Ответ 5
В настоящее время мы используем Caliburn и модульные тесты способом, описанным в этой статье Тестирование привязок в WPF. Недостаток этого решения, разработчик пользовательского интерфейса пишет код, который имеет смысл только проверять привязки и может быть опущен, если MS (или кто-то) будет писать компилятор проверки XAML.
Ответ 6
Я согласен с предыдущим ответом. Это "по дизайну", и нет способа проверить его во время компиляции.
Я тоже нашел боль.
Лучшим и единственным способом, который я нашел, является проверка вывода отладки Visual Studio во время выполнения. Любая ошибка привязки будет напечатана, как только вы откроете окно, содержащее ее.
Я согласен, если вы считаете это дрянным и ненадежным методом, но он должен работать, если у вас нет большого количества окон. Вы можете создать полуформальную тестовую практику, когда время от времени вы открываете любое окно, которое ищет конкретные ошибки привязки.