Наследование стиля с помощью UserControl

#c# #wpf #user-controls

#c# #wpf #пользовательские элементы управления

Вопрос:

Я пытаюсь настроить стиль usercontrol, унаследовав его стиль и добавив к нему некоторые дополнительные стили. Я сделал небольшой проект, чтобы попробовать это. Допустим, у меня есть вызываемый пользовательский элемент управления UserControl1 (то, что он содержит, не имеет значения — в моем примере проекта он пуст).

Я использую его в своем MainWindow следующим образом:

 <Window x:Class="WpfStyleInheritance.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfStyleInheritance"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <local:UserControl1>
            <local:UserControl1.Style>
                <Style TargetType="{x:Type local:UserControl1}" BasedOn="{x:Type local:UserControl1}">
                    <Setter Property="Margin" Value="0" />
                </Style>
            </local:UserControl1.Style>
        </local:UserControl1>
    </Grid>
</Window>
 

Со BasedOn своей стороны, я получаю ошибку:

Указанное значение не может быть присвоено. Ожидался следующий тип: «Стиль».

Если я изменю его на BasedOn="{StaticResource {x:Type local:UserControl1}}" , то получу сообщение об ошибке:

Не удалось разрешить ресурс «{x:Type local:UserControl1}».

Как я могу заставить это работать и жить долго и счастливо?

Редактировать: как я написал в комментариях к ответу здесь, если я иду по маршруту StaticResource и запускаю, я получаю исключение XamlParseException с сообщением:

Не удается найти ресурс с именем ‘WpfStyleInheritance.UserControl1’. Имена ресурсов чувствительны к регистру.

Дополнительная информация: если я заменю все экземпляры local:UserControl1 в разметке MainWindow на Button , это работает довольно хорошо. Проблема заключается в пользовательских элементах управления.

Редактировать 2: если я добавлю стиль в UserControl, проблема останется:

 <UserControl.Style>
    <Style TargetType="UserControl">
        <Setter Property="Height" Value="0" />
    </Style>
</UserControl.Style>
 

Ответ №1:

BasedOn синтаксис неверен. Это должно быть:

 BasedOn="{StaticResource {x:Type local:UserControl1}}"
 

И даже если вы получаете ошибку конструктора, попробуйте повторно скомпилировать свой код. Убедитесь, что добавленное пространство имен правильно сопоставлено с вашим UserControl.

Кроме того, убедитесь, что MainWindow и UserControl1 находятся в одной сборке.

Если они находятся в разных сборках, необходимо указать имя сборки в объявлении пространства имен:

 xmlns:local="clr-namespace:WpfStyleInheritance;assembly=AssemblyName"
 

Обновить

В случае, если вы не определили какой-либо стиль по умолчанию для UserControl1 , вам не нужно использовать BasedOn , поскольку стиля по умолчанию для вашего UserControl не существует. Вот почему вы получаете исключение.

Удалите BasedOn, и он будет работать нормально.


Ресурс, который вы определили в XAML, — это не стиль по умолчанию, а локальный стиль UserControl, который будет переопределен в случае определения другого локального ресурса в MainWindow.

Если вам нужен стиль по умолчанию для вашего UserControl1, объявите его в разделе Application resources , то есть в App.xaml .

 <Application.Resources>
   <Style TargetType="{x:Type local:UserControl1}">
      <Setter Property="Height" Value="0" />
   </Style>
</Application.Resources>
 

и теперь в MainWindow.xaml это будет работать нормально:

 <local:UserControl1>
    <local:UserControl1.Style>
        <Style TargetType="{x:Type local:UserControl1}"
               BasedOn="{StaticResource {x:Type local:UserControl1}}">
            <Setter Property="Margin" Value="0" />
        </Style>
    </local:UserControl1.Style>
</local:UserControl1>
 

Комментарии:

1. Я попробовал это, как я объяснил в вопросе. Если я запускаю, я получаю исключение XamlParseException

2. Можете ли вы опубликовать внутреннее исключение для XamlParseException?

3. Не удается найти ресурс с именем ‘WpfStyleInheritance. UserControl1’. Имена ресурсов чувствительны к регистру.

4. Можете ли вы опубликовать код для UserControl1? Скорее всего, сборка отличается или имя неверно.

5. Это просто пустой UserControl, который вы получаете после добавления нового элемента.