В моем последнем задании я работал над вирусным сканером. Для создания вещи легче для меня отладить у меня был большой вход застрявшего повсеместно, но в пользующемся высоким спросом приложении как этот, расход вызова функции является просто слишком дорогим. Так, я придумал этот небольшой Макрос, который все еще позволил мне включать отладку, входящую в систему, версия выпуска на потребительском сайте, без стоимости вызова функции проверит флаг отладки и просто возвратится, ничего не регистрируя, или, если включено, сделала бы вход... Макрос был определен следующим образом:
#define dbgmsg(_FORMAT, ...) if((debugmsg_flag & 0x00000001) || (debugmsg_flag & 0x80000000)) { log_dbgmsg(_FORMAT, __VA_ARGS__); }
из-за VA_ARGS в функциях журнала, это было хорошим случаем для макроса как это.
Прежде, который, я использовал макрос в приложении высокой безопасности, которое должно было сказать пользователю, что у них не было корректного доступа, и он скажет им, что отмечает, им было нужно.
Макрос (макросы), определенный как:
#define SECURITY_CHECK(lRequiredSecRoles) if(!DoSecurityCheck(lRequiredSecRoles, #lRequiredSecRoles, true)) return
#define SECURITY_CHECK_QUIET(lRequiredSecRoles) (DoSecurityCheck(lRequiredSecRoles, #lRequiredSecRoles, false))
Затем мы могли просто опрыснуть проверки на всем протяжении UI, и он скажет Вам, каким ролям позволили выполнить действие, которое Вы пытались сделать, если у Вас уже не было той роли. Причина для двух из них состояла в том, чтобы возвратить значение в некоторых местах и возврат из пустой функции в других...
SECURITY_CHECK(ROLE_BUSINESS_INFORMATION_STEWARD | ROLE_WORKER_ADMINISTRATOR);
LRESULT CAddPerson1::OnWizardNext()
{
if(m_Role.GetItemData(m_Role.GetCurSel()) == parent->ROLE_EMPLOYEE) {
SECURITY_CHECK(ROLE_WORKER_ADMINISTRATOR | ROLE_BUSINESS_INFORMATION_STEWARD ) -1;
} else if(m_Role.GetItemData(m_Role.GetCurSel()) == parent->ROLE_CONTINGENT) {
SECURITY_CHECK(ROLE_CONTINGENT_WORKER_ADMINISTRATOR | ROLE_BUSINESS_INFORMATION_STEWARD | ROLE_WORKER_ADMINISTRATOR) -1;
}
...
Так или иначе, это - то, как я использовал их, и я не уверен, как этому, возможно, помогли с шаблонами... Кроме этого, я стараюсь избегать их, если не ДЕЙСТВИТЕЛЬНО необходимо.
Первый подход - использовать ComboBox, потому что он уже имеет такую функциональность. Вы можете использовать его функцию TextSearch. Чтобы включить эту функцию, используйте следующий код (извините, он быстрый и грязный):
<ComboBox ItemsSource="{Binding AutoSuggestionVariants}">
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="TextSearch.Text" Value="{Binding}" />
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
Также, если он вам нужен, вы можете изменить стиль поля со списком так, чтобы оно выглядело как текстовое поле (кнопка удаления и всплывающий список).
Другой подход - использовать CollectionView. В этой статье описывается, как выполнять те же функции, что и TextSearch для поля со списком. Я думаю, вы можете перенести эту идею на текстовое поле.
Надеюсь, это поможет.