Использование шаблона элемента управления для всех элементов управления в приложении

У меня есть шаблон элемента управления на одной из моих страниц, и я назначаю этот шаблон свойству Validation.ErrorTemplate своего текстового поля. Следующий код даст вам лучшее представление.

<ControlTemplate x:Key="ValidationErrorTemplate">
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                <AdornedElementPlaceholder/>
                <Image Name="ValidizorImage" Stretch="None" Source="validizor.gif" ToolTip="{Binding [0].ErrorContent}" ToolTipService.InitialShowDelay="0" ToolTipService.ShowDuration="60000"/>
            </StackPanel>
</ControlTemplate>

Приведенный выше шаблон устанавливает изображение в конце текстового поля, в котором возникает ошибка. Этот шаблон используется, как показано ниже.

<TextBox Grid.Column="5" Grid.Row="1" x:Name="txtemail" Grid.ColumnSpan="3" Margin="0,1,20,1" Validation.ErrorTemplate="{StaticResource ValidationErrorTemplate}"  />

Вот мой вопрос

Я хочу переместить этот шаблон управления за пределы этой страницы, чтобы можно было использовать его во всем приложении.

Я попытался поместить тот же код шаблона элемента управления в пользовательский элемент управления, скажем "ErrorUC"

<UserControl...>
    <Grid>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
            <AdornedElementPlaceholder/>
            <Image Name="ValidizorImage" Stretch="None" Source="validizor.gif" ToolTip="{Binding [0].ErrorContent}" ToolTipService.InitialShowDelay="0" ToolTipService.ShowDuration="60000"/>
        </StackPanel>
    </Grid>
</UserControl>

и использовал его, как показано ниже

TextBox1.SetResourceReference
(System.Windows.Controls.Validation.ErrorTemplateProperty, new ErrorUC());

Выполнив приведенный выше код, я узнал, что «AdornedElementPlaceholder» можно использовать только в шаблонах, а не в пользовательских элементах управления. Если я прокомментирую то же самое, я не получаю желаемого результата.


person samar    schedule 19.04.2010    source источник


Ответы (2)


Свойство Validation.ErrorTemplate ожидает ControlTemplate и нет UserControl. Вот почему ваш код не работает. Вам лучше сохранить «ValidationErrorTemplate» и поместить его в общий ResourceDictionary, к которому вы можете получить доступ везде в вашем приложении (или там, где вам это нужно). Например, вы можете поместить его в свой App.xaml, а затем ссылаться на него, используя DynamicResource.


РЕДАКТИРОВАТЬ: Хорошо, теперь мы переходим к более подробному объяснению. Если это не является обязательным требованием, я думаю, вам лучше работать с XAML вместо того, чтобы слишком много кода загружать ResourceDictionaries и назначать свойства. Вы можете легко добиться желаемого поведения в XAML следующим образом:

Откройте файл с именем «App.xaml» в своем проекте приложения WPF. Visual Studio / Blend автоматически создаст этот файл за вас. Этот файл содержит раздел <Application.Resources>. Добавьте свой ControlTemplate в этот раздел:

<Application.Resources>
    <ControlTemplate x:Key="ValidationErrorTemplate">
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
            <AdornedElementPlaceholder/>
            <Image Name="ValidizorImage" Stretch="None" Source="validizor.gif" ToolTip="{Binding [0].ErrorContent}" ToolTipService.InitialShowDelay="0" ToolTipService.ShowDuration="60000"/>
        </StackPanel>
    </ControlTemplate>
</Application.Resources>

Теперь просто назначьте этот шаблон ошибки своим элементам управления, используя свойство Validation.ErrorTemplate следующим образом:

<TextBox ... Validation.ErrorTemplate="{DynamicResource ValidationErrorTemplate}" />

Конечно, у вас должна быть привязка с ValidationRules, определенная для соответствующих свойств элемента управления (например, свойство Text TextBox). В простом приложении у меня работает этот код: изображение отображается в случае сбоя проверки.

Я не являюсь экспертом в выполнении всего этого в коде, так как предпочитаю XAML для определения пользовательского интерфейса. Но насколько я могу судить, ваш код мне кажется нормальным. Действительно ли проверка терпит неудачу? Убедитесь в этом, удалив Validation.ErrorTemplate. Если ваш TextBox имеет красную рамку, значит, он не работает - иначе в вашей логике проверки может быть ошибка ?!

HTH, геххо.

person gehho    schedule 19.04.2010
comment
привет, я попробовал ваше решение. Пожалуйста, проверьте этот пост, так как я не могу уместить свой запрос в разделе комментариев. - person samar; 19.04.2010
comment
привет, я получил это, добавив следующий код в xaml напротив текстового поля, где мне нужен шаблон для работы. Validation.ErrorTemplate = {DynamicResource ValidationErrorTemplate} Но можем ли мы внести вышеупомянутое в код позади. Что-то похожее на TextBox1.SetResourceReference (Validation.ErrorTemplateProperty, ct); упомянутый выше?? Пожалуйста, дайте мне знать. - person samar; 19.04.2010
comment
Как я уже сказал, я не являюсь экспертом в этом коде. Согласно MSDN, SetResourceReference (...) должен быть похож на DynamicResource, но они не содержат никаких подробностей о различиях. Во всяком случае, я думаю, что то же самое и для этого сценария. Ваш вызов System.Windows.Application.Current.Resources["ValidationErrorTemplate"]; возвращает какое-либо значение или это null? Если это null, вам следует подумать об использовании вместо этого this.FindResource(...). - person gehho; 19.04.2010
comment
привет, ваше решение было довольно крутым, и вы получили его через xaml. Я также получил это через код, также через следующий код. TextBox1.SetResourceReference (Validation.ErrorTemplateProperty, ValidationErrorTemplate); Я без необходимости помещал ресурс в шаблон элемента управления, а затем использовал его. :) Большое спасибо за вашу помощь, время и терпение. С уважением, Самар - person samar; 20.04.2010
comment
Это даже недопустимо в app.xaml - в нем говорится, что он ожидает тип словаря ресурсов на этом уровне. - Поместить его в словарь не получится, потому что тогда нужен ключ. - person BrainSlugs83; 23.04.2020

Я пробовал твое решение

а) Я добавил в проект dictionary.xaml и добавил в него свой шаблон элемента управления как

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ControlTemplate x:Key="ValidationErrorTemplate">
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
            <AdornedElementPlaceholder/>
            <Image Name="ValidizorImage" Stretch="None" Source="validizor.gif" ToolTip="{Binding [0].ErrorContent}" ToolTipService.InitialShowDelay="0" ToolTipService.ShowDuration="60000"/>
        </StackPanel>
    </ControlTemplate>
</ResourceDictionary>

б) Я добавил этот словарь в свои ресурсы приложения как

Uri uri = new Uri("my dictionary uri", UriKind.RelativeOrAbsolute);

            ResourceDictionary dict = new ResourceDictionary();
            dict.Source = uri;
            Application.Current.Resources.MergedDictionaries.Add(dict);

c) Я попытался получить доступ к словарю как

ControlTemplate ct = (ControlTemplate)System.Windows.Application.Current.Resources["ValidationErrorTemplate"];
TextBox1.SetResourceReference(Validation.ErrorTemplateProperty, ct);

Тем не менее мой шаблон управления не прикрепляется. Я проверил, есть ли шаблон элемента управления в ресурсах приложения, и обнаружил, что он действительно есть, т.е. следующая строка дает мне истину

Application.Resources.Contains("ValidationErrorTemplate");

Я что-то здесь упускаю ??

Спасибо,

Самар

person samar    schedule 19.04.2010