首页 文章

在使用ControlTemplates定义的程序集中定义的自定义控件

提问于
浏览
0

我创建了一个带有自定义控件的库,以简化我的同事的一些开发 . 然后我创建了一个模板,我想让他们有机会修改默认模板等等 . 经过一些研究,我发现了一些关于Themes,Generic.xaml和ThemeInfo属性的信息,但有些东西不起作用 .

所以我的最后一次尝试: - AssemblyInfo.cs中带有Theme属性的控件库:

[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中没有控制模板的情况下渲染控件 .

要成功显示控件,我必须在app.xaml中添加generic.xaml文件作为ResourceDictionary,而我在第二个程序集中添加ThemeInfo属性 .

另一个相关问题:如果在window.xaml文件或另一个控件xaml文件中,为了使用样式的强大功能,我添加:

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

系统似乎覆盖generic.xaml中定义的样式,并且不再呈现控件模板 . 要检查我在属性网格中查看了Template属性,并且在同一程序集中定义自定义控件时,值的原点被引用为“在样式中定义”而不是经典的“继承” .

所以我的问题,有人可以指出我应该在哪里克服这种情况或帮助我找到正确的方法来准备这样的设置:在类库中定义控件,并使用默认样式机制,在一个库中定义控件模板wpf应用程序中的generic.xaml文件?

提前致谢 !

Update:

我已经看了一些事情并且更清楚了:因为我不打算以一般方式使用主题,所以我必须以某种方式设置样式系统以使用客户库中定义的resourcedictionnary作为“通用”词典 .

通过在源程序集中添加ThemeInfo(... None,... None)并将客户xaml文件作为资源添加到客户程序集中,我设法将 DependencyPropertyHelper.GetValueSource(customControl1, Library.CustomControl.TemplateProperty).BaseValueSource 返回的值从 Style 更改为 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属性的源仍然设置为Style ...

我想我现在正在寻找一种方式将样式设置为隐式或默认或某种东西..(在客户程序集中为源程序集中定义的控件定义的那种) .

1 回答

  • 0

    我不完全清楚哪个部分不起作用以及您想要给同事修改默认外观的模板,但这就是您需要在WPF中使用自定义控件所做的事情:

    创建继承自的自定义控件类

    System.Windows.Controls.Control
    

    您正确获得了构造函数部分,因此下一步是在与自定义控件相同的项目中创建一个名为“Themes”的文件夹,并在其中添加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来绑定这些属性,而不是对它们进行硬编码 .

相关问题