C# 将样式应用于从某个基类派生的控件

C# 将样式应用于从某个基类派生的控件,c#,wpf,xaml,custom-controls,C#,Wpf,Xaml,Custom Controls,如何将样式应用于基于某个CustomControl的所有子项 示例 自定义控件 public class SubView : UserControl { ... } public partial class MyView : SubView { ... } 基于CustomControl的控件 public class SubView : UserControl { ... } public partial class MyView : SubView { ... } 用于MyView的

如何将样式应用于基于某个CustomControl的所有子项

示例

自定义控件

public class SubView : UserControl
{ ... }
public partial class MyView : SubView
{ ... }
基于CustomControl的控件

public class SubView : UserControl
{ ... }
public partial class MyView : SubView
{ ... }
用于MyView的XAML

<myLibrary:SubView
    xmlns:myLibrary="....">

<Grid>
    <!--Any content-->
</Grid>
</moduleChrome:SubView>

父级(此网格的子级是从代码运行时设置的)


如何让MyView受到样式的影响

编辑

这段代码的起源是动态的,相当复杂,但我试图使问题尽可能通用,以便尽可能多的人可以得到可能的解决方案的帮助,但我想我把它做得太通用了。
这些答案可能不会对我有所帮助,但我希望其他人会有所帮助。

样式只适用于特定的类,不会被继承。不过,您可以这样做:

<Style TargetType="{x:Type myLibrary:SubView}">
    <Setter Property="Opacity" Value="0.5"/>
</Style>
<Style TargetType="{x:Type localFolder:MyView}" BasedOn="{StaticResource {x:Type myLibrary:SubView}} />


样式只应用于特定的类,不会被继承。不过,您可以这样做:

<Style TargetType="{x:Type myLibrary:SubView}">
    <Setter Property="Opacity" Value="0.5"/>
</Style>
<Style TargetType="{x:Type localFolder:MyView}" BasedOn="{StaticResource {x:Type myLibrary:SubView}} />


如果
子视图
实际上是一个自定义控件,而不是
用户控件
,并且在Themes/Generic.xaml中定义了一个默认模板,那么这实际上可以按预期工作

您可以使用以下示例代码自己确认这一点

Themes/Generic.xaml:

<Style TargetType="local:SubView">
    <Setter Property="Opacity"  Value="0.5" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:SubView}">
                <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>
public class SubView : ContentControl
{
    static SubView()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(SubView),
            new FrameworkPropertyMetadata(typeof(SubView)));
    }
}

public class MyView : SubView
{

}
<local:SubView>
    <local:SubView.Content>
        <TextBlock>content 1</TextBlock>
    </local:SubView.Content>
</local:SubView>
<local:MyView>
    <local:SubView.Content>
        <TextBlock>content 2</TextBlock>
    </local:SubView.Content>
</local:MyView>
用法:

<Style TargetType="local:SubView">
    <Setter Property="Opacity"  Value="0.5" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:SubView}">
                <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>
public class SubView : ContentControl
{
    static SubView()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(SubView),
            new FrameworkPropertyMetadata(typeof(SubView)));
    }
}

public class MyView : SubView
{

}
<local:SubView>
    <local:SubView.Content>
        <TextBlock>content 1</TextBlock>
    </local:SubView.Content>
</local:SubView>
<local:MyView>
    <local:SubView.Content>
        <TextBlock>content 2</TextBlock>
    </local:SubView.Content>
</local:MyView>

内容1
内容2
从MSDN:

:“如果您确实需要创建一个新控件,最简单的方法是创建一个派生自UserControl的类。在这样做之前,请考虑您的控件不支持模板,因此将不支持复杂的定制。”


如果
子视图
确实是一个自定义控件而不是
用户控件
,并且在Themes/Generic.xaml中定义了一个默认模板,那么这实际上将按预期工作

您可以使用以下示例代码自己确认这一点

Themes/Generic.xaml:

<Style TargetType="local:SubView">
    <Setter Property="Opacity"  Value="0.5" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:SubView}">
                <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>
public class SubView : ContentControl
{
    static SubView()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(SubView),
            new FrameworkPropertyMetadata(typeof(SubView)));
    }
}

public class MyView : SubView
{

}
<local:SubView>
    <local:SubView.Content>
        <TextBlock>content 1</TextBlock>
    </local:SubView.Content>
</local:SubView>
<local:MyView>
    <local:SubView.Content>
        <TextBlock>content 2</TextBlock>
    </local:SubView.Content>
</local:MyView>
用法:

<Style TargetType="local:SubView">
    <Setter Property="Opacity"  Value="0.5" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:SubView}">
                <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>
public class SubView : ContentControl
{
    static SubView()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(SubView),
            new FrameworkPropertyMetadata(typeof(SubView)));
    }
}

public class MyView : SubView
{

}
<local:SubView>
    <local:SubView.Content>
        <TextBlock>content 1</TextBlock>
    </local:SubView.Content>
</local:SubView>
<local:MyView>
    <local:SubView.Content>
        <TextBlock>content 2</TextBlock>
    </local:SubView.Content>
</local:MyView>

内容1
内容2
从MSDN:

:“如果您确实需要创建一个新控件,最简单的方法是创建一个派生自UserControl的类。在这样做之前,请考虑您的控件不支持模板,因此将不支持复杂的定制。”


那么你在寻找什么答案?如果你想要的话,为什么不创建一个真正的自定义控件呢?@mm8它是一个“真正的”自定义控件。子视图替代了另一个名为View的自定义控件中的usercontrols,这些视图托管在名为“ViewHost”的“main”控件中。“视图”和“子视图”都有一个称为ViewGate的依赖类(它允许视图和主应用程序之间的通信),我想做的是将“视图”的ViewGate绑定到它的子视图(子视图)ViewGates由于ViewGate具有动态属性,因此这与您最初关于如何应用基类样式的问题有何关系?@mm8我认为可以在样式中设置的共享依赖属性。我更新了问题“如何将风格应用于所有基于某个自定义控件的儿童”的原始问题已经得到了回答,不是吗?在我的答案中,我在示例代码中设置了不透明度依赖属性,它显然可以工作。如果你有其他问题,请问一个新问题。那么你在寻找什么答案?如果你想要的话,为什么不创建一个真正的自定义控件呢?@mm8它是一个“真正的”自定义控件。子视图替代了另一个名为View的自定义控件中的usercontrols,这些视图托管在名为“ViewHost”的“main”控件中。“视图”和“子视图”都有一个称为ViewGate的依赖类(它允许视图和主应用程序之间的通信),我想做的是将“视图”的ViewGate绑定到它的子视图(子视图)ViewGates由于ViewGate具有动态属性,因此这与您最初关于如何应用基类样式的问题有何关系?@mm8我认为可以在样式中设置的共享依赖属性。我更新了问题“如何将风格应用于所有基于某个自定义控件的儿童”的原始问题已经得到了回答,不是吗?在我的答案中,我在示例代码中设置了不透明度依赖属性,它显然可以工作。如果您有其他问题,请提出新问题。