Пользовательский элемент управления, определенный в сборке с шаблонами ControlTemplates, определенными в другом - PullRequest
0 голосов
/ 14 октября 2011

Я создал библиотеку с пользовательскими элементами управления, чтобы упростить некоторые разработки моих коллег.Затем я создал шаблон, в котором я хотел бы дать им возможность изменять шаблоны по умолчанию и так далее.После некоторых исследований я нашел некоторую информацию о атрибутах Themes, Generic.xaml и ThemeInfo, но что-то не работает.

Итак, моя последняя попытка: - Библиотека элементов управления с атрибутом Theme в AssemblyInfo.cs:

[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //où se trouvent les dictionnaires de ressources spécifiques à un thème
//(utilisé si une ressource est introuvable dans la page, 
// ou dictionnaires de ressources de l'application)
ResourceDictionaryLocation.ExternalAssembly //où se trouve le dictionnaire de ressources générique
//(utilisé si une ressource est introuvable dans la page, 
// dans l'application ou dans l'un des dictionnaires de ressources spécifiques à un thème)

)]

Все элементы управления наследуются от System.Windows.Control и имеют статический конструктор с:

DefaultStyleKeyProperty.
         OverrideMetadata(typeof(Tire), new FrameworkPropertyMetadata(typeof(Tire))); 

Затем в приложении, на которое ссылается эта библиотекаУ меня есть файл Themes / Generic.xaml с такими определениями:

<Style TargetType="{x:Type g:Tire}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type g:Tire}">
                <Viewbox Name="view">
                    <Ellipse Stroke="Black" StrokeThickness="10" Width="30" 
                             Height="30"/>
                </Viewbox>
                <ControlTemplate.Triggers>
                    <DataTrigger Binding="{Binding Present}" Value="true">
                        <Setter TargetName="view" Property="Visibility" Value="Visible"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Present}" Value="false">
                        <Setter TargetName="view" Property="Visibility" Value="Collapsed"/>
                    </DataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Я также пытался установить ключ с помощью {x:Type g:Tire} ou simplement g:Tire, но безуспешно: элементы управления отображаются без шаблонов элементов управления вVS2010.

Чтобы успешно отобразить элементы управления, мне нужно добавить файл generic.xaml в качестве ResourceDictionary в app.xaml, тогда как я добавляю атрибут ThemeInfo или нет в этой второй сборке.

Другая связанная с этим проблема: если в файле window.xaml или другом контрольном файле xaml, чтобы использовать мощь стилей, я добавляю:

<Style TargetType="{x:Type g:Tire}">
    <Setter Property="Width" Value="20"/>
</Style>

система перезаписываетсяСтиль, определенный в generic.xaml, и шаблон элемента управления больше не отображаются.Чтобы проверить, я посмотрел на свойство Template в сетке свойств и источник значения упоминается как «Определено в стиле» вместо классического «Наследования», когда в той же сборке определен пользовательский элемент управления.

Поэтому мой вопрос: может ли кто-нибудь указать мне, куда мне следует обратиться, чтобы преодолеть эту ситуацию, или помочь мне найти правильный способ подготовки такой установки: определить элементы управления в библиотеке классов и, используя механизм стилей по умолчанию, определить шаблоны элементов управления вФайл generic.xaml в приложении wpf?

Заранее спасибо!

Обновление:

Я посмотрел несколько вещей, и этонемного более ясно: поскольку я не собираюсь использовать их в общих чертах, я должен каким-то образом установить систему стилей, чтобы использовать ресурсный словарь, определенный в библиотеке клиента, как «универсальный» словарь.

Добавив ThemeInfo (... None, ... None) в исходную сборку и добавив xaml-файл клиента в качестве ресурса в пользовательскую сборку, мне удалось изменить значение, возвращаемое DependencyPropertyHelper.GetValueSource(customControl1, Library.CustomControl.TemplateProperty).BaseValueSource из *От 1036 * до Default, но шаблон по-прежнему перезаписывается, если в приложении определен стиль:

<Window x:Class="WpfApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525" xmlns:my="clr-namespace:Library;assembly=Library">
<Grid>
    <Grid.Resources>
        <Style TargetType="my:CustomControl"></Style>
    </Grid.Resources>
    <my:CustomControl HorizontalAlignment="Left" Margin="128,95,0,0" Name="customControl1" VerticalAlignment="Top" Height="157" Width="253" />
</Grid>

Кроме того, в сетке свойств источником свойства Template являетсявсе еще установлен как стиль ...

Я думаю, что сейчас я ищу способ установить стиль как неявный или по умолчанию или что-то еще ... (тот, который определен в пользовательской сборке для элемента управления, определенного в исходной сборке).

1 Ответ

0 голосов
/ 14 октября 2011

Мне не совсем ясно, какая часть не работает и какой шаблон вы хотите дать своим коллегам для изменения внешнего вида по умолчанию, но это то, что вам нужно сделать с пользовательскими элементами управления в WPF:

Создайте пользовательский класс элемента управления, унаследованный от

System.Windows.Controls.Control

. Вы правильно получили конструктор, поэтому следующий шаг - создать папку в том же проекте, что и ваш пользовательский элемент управления с именем «Темы», и добавить Generic.XAML там.Вот где WPF будет искать шаблон элемента управления по умолчанию.

Определите стиль, который реализует ваш целевой тип:

<Style TargetType="{x:Type local:Tire}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:Tire}">
                <!--  there goes your template: grids / stackpanels, etc -->

Для каждого проекта, в котором вы хотите использовать элемент управления, у вас есть шансчтобы переопределить стиль:

<Style TargetType="{x:Type custom:Tire}">
    <Setter Property="Width" Value="150"/>
    <!-- any customer dependency property can be set here as well-->

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

...