Стилизация производного UserControl приводит к его исчезновению - PullRequest
0 голосов
/ 31 мая 2018

У меня есть элемент управления PaneBase, который происходит от UserControl.Там нет XAML, это просто элемент управления.Тип UserControl относится к типу Catel, но я все еще наблюдаю эту проблему при использовании System.Windows.Controls.UserControl.

public class PaneBase : UserControl
{
    public static readonly DependencyProperty TitleProperty =
        DependencyProperty.Register("Title",
                                    typeof(string),
                                    typeof(PaneBase),
                                    new PropertyMetadata(default(string)));

    public string Title
    {
        get => (string) GetValue(TitleProperty);
        set => SetValue(TitleProperty, value);
    }
}

. У меня есть другой элемент управления EquationPane, который происходит от PaneBase и имеетXAML:

EquationPane.xaml

<local:PaneBase x:Class="EngineersToolkit.Windows.Views.Panes.EquationPane"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:catel="http://schemas.catelproject.com" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                xmlns:local="clr-namespace:EngineersToolkit.Windows.Views.Panes"
                xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                Title="Equation"
                d:DataContext="{d:DesignData EquationPaneViewModel}" d:DesignHeight="450" d:DesignWidth="800"
                mc:Ignorable="d">
    <Grid>
        <TextBox Width="150" Height="30"
                 Text="{Binding Equation, Mode=TwoWay}" />

    </Grid>
</local:PaneBase>

EquationPane.xaml.cs

public partial class EquationPane
{
    public EquationPane()
    {
        InitializeComponent();
        DataContext = new EquationPaneViewModel();
    }
}

Все это работаетдо сих пор, когда я включаю EquationPane в окно, оно отображается нормально:

<Grid>
    <panes:EquationPane Width="100" Height="100"
                        HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                        Background="Aqua" />

</Grid>

enter image description here

Это продолжает работать правильно, еслиЯ пытаюсь стилизовать элемент управления:

<Style TargetType="{x:Type panes:EquationPane}">
    <Setter Property="Background" Value="Red" />
</Style>

Однако все начинает разваливаться, если я вместо этого нацеливаю стиль на PaneBase.Если я изменю TargetType на PaneBase, то стиль просто не будет применен.Однако если я переопределю метаданные свойства зависимостей в PaneBase следующим образом:

static PaneBase()
{
    DefaultStyleKeyProperty.OverrideMetadata(typeof(PaneBase),
                                             new FrameworkPropertyMetadata(
                                                 typeof(PaneBase)));
}

Тогда элемент управления вообще прекратит рендеринг, оставив меня с пустым окном.Почему это происходит?

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Почему это происходит?

Элементы управления WPF выглядят «безликими», что означает, что они не имеют внешнего вида, если вы не определите для них шаблон.

Следующее указываетчто для PaneBase в themes/generic.xaml определен стиль по умолчанию:

static PaneBase()
{
    DefaultStyleKeyProperty.OverrideMetadata(typeof(PaneBase),
                                         new FrameworkPropertyMetadata(
                                             typeof(PaneBase)));
}

Затем следует определить такой стиль:

<Style TargetType="local:PaneBase">
    <Setter Property="Background" Value="Red" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type UserControl}">
                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Если вы удалите статический конструктор в PanelBase он унаследует шаблон от стиля базового класса UserControl.

Если вы затем определите Style для PaneBase, например:

<Style TargetType="{x:Type local:PaneBase}">
    <Setter Property="Background" Value="Red" />
</Style>

...it больше не имеет шаблона, и поэтому вы не видите элемент управления в своем окне.

0 голосов
/ 31 мая 2018

Неявные стили не применяются автоматически к производным типам.Чтобы применить стиль PaneBase к EquationPane, вы можете выполнить одно из следующих действий:

1. Запишите это на EquationPane.xaml.cs

public EquationPane() 
    {
        this.SetResourceReference(StyleProperty, typeof(PaneBase));
    }

2. Явно укажите стиль, гдеИспользуется EquationPane

<panes:EquationPane Style="{DynamicResource {x:Type PaneBase}}"/>

3. Определите стиль, основанный на родительском стиле

<Style x:Key="{x:Type PaneBase}" TargetType="{x:Type PaneBase}">
      <Setter Property="Background" Value="Red" />
</Style>

<Style TargetType="{x:Type panes:EquationPane}" BasedOn="{StaticResource {x:Type PaneBase}}"/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...