Итак, чтобы подвести итог, я хочу один элемент управления, который может работать в несколько разных режимах или состояниях. Режим также может влиять на свойства XAML и логику кода.
Кажется, что VisualStateManager очень ограничен в том, какими свойствами он может манипулировать. Но когда различия только визуальные, это лучший выбор.
При наличии других различий в XAML очевидным выбором является исключение этих свойств из XAML и установка их в коде, как в ctor. Более приятным способом является предоставление этих свойств в качестве свойств зависимостей в коде, привязка к этим свойствам в XAML пользовательского элемента управления, а затем вы можете указать эти свойства в других XAML, где вы используете этот пользовательский элемент управления. Когда вашему элементу управления не важно, что находится в этих свойствах, тогда это также хороший выбор дизайна. В моем случае, однако, при настройке этих различных свойств ответственность должна быть возложена на сам пользовательский элемент управления, а не на его родительский элемент, и я хочу предоставить только однорежимное свойство, это нехорошо.
Для этого случая лучший способ, который я нашел до сих пор, это:
- создать обычный пользовательский элемент управления (код XAML +), выставить отличающиеся свойства (простые, а не DP) и связать их с XAML
- сделать этот пользовательский элемент управления абстрактным и, возможно, некоторые свойства тоже
- для каждого отдельного режима, который должен поддерживать элемент управления, получить класс из этого базового элемента управления (только код, без XAML), предоставить реализации для абстрактных свойств
- вместо использования базового элемента управления в других местах, используйте одну из производных реализаций
Таким образом, вы можете легко указать извне, в каком режиме вы хотите, чтобы ваш элемент управления работал. Недостатком является то, что изменить режим нелегко, так как вам нужно изменить не свойство, а тип и экземпляр объекта. управление.
И, наконец, когда есть различия в логике кода, то один из способов - раскрыть свойство mode или использовать метод абстрактного класса, который я описал выше. Например, функция обработчика нажатия кнопки также может быть абстрактной.