如何在同一个库中有多个 wpf 自定义控件?

how to have many wpf custom controls in the same library?

我有一个 WPF 自定义控件项目,我想在其中包含许多自定义控件。默认情况下,VS2015 cummunity 创建一个 Theme 文件夹,其中包含一个 generic.xaml 文件和一个带有交互逻辑的 .cs 文件。

我想要有很多用户控件,所以我尝试创建一个 MyControl1 文件夹,在这个文件夹中,我创建了一个 Theme 文件夹并添加了一个新项目,一个 WPF 自定义控件。但它不会为此控件创建 generic.xaml。我从根文件夹复制默认 generic.xaml 并创建我的样式,但是当我在我的 WPF 应用程序中使用该控件时,我看不到该控件。

我看过这个post:Custom control Lib with multiple controls and generic.xaml但我真的不太明白这个解决方案。

我有一个问题,在 MyControl1.Generic.xaml 你有这个代码:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:CustomControls.Calendario2">


    <Style TargetType="{x:Type local:CalendarioMes2}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:CalendarioMes2}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">

                        <Grid>
                            <TextBox Text="Prueba"/>
                            <Label Content="Prueba"/>
                        </Grid>

                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

但是我在这一行中得到一个错误:

<Style TargetType="{x:Type local:CalendarioMes2}">

无法从文本创建类型 local:CalendarioMes2。

如果我在一个只有一个自定义控件的库中使用这段代码,并且这段代码在 generic.xaml 文件中,它就可以工作。

所以,总而言之,我想知道如何才能拥有一个包含许多自定义控件的库。

谢谢。

我发现最简洁的方法是创建合并字典。 CustomControl 往往继承自基本控件,因此我将按 ListView、TextBox 等对它们进行分组。

Generic.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/YourAssembly;component/ResourceDictionaries/ListView.xaml"/>
        <ResourceDictionary Source="/YourAssembly;component/ResourceDictionaries/TabControl.xaml"/>
        <ResourceDictionary Source="/YourAssembly;component/ResourceDictionaries/TextBox.xaml"/>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

TextBox.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:Local="clr-namespace:YourNameSpace">

 <!-- Describes how to style a ValidatedTextBox -->
    <Style x:Key="{x:Type Local:ValidatedTextBox}" BasedOn="{StaticResource {x:Type TextBox}}" TargetType="{x:Type Local:ValidatedTextBox}">
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Border BorderBrush="Red" BorderThickness="1" VerticalAlignment="Top">
                            <AdornedElementPlaceholder x:Name="adorner" />
                        </Border>
                        <Border x:Name="validationErrorsContainer" Background="LightCoral" BorderBrush="Red" BorderThickness="1" Margin="5, 0, 0, 0" VerticalAlignment="Top">
                            <ListView Background="Transparent" BorderThickness="0" Focusable="False" IsHitTestVisible="False"
                                      ItemsSource="{Binding AdornedElement.(Validation.Errors), ElementName=adorner}">
                                <ListView.Resources>
                                    <Style TargetType="{x:Type GridViewColumnHeader}">
                                        <Setter Property="Visibility" Value="Collapsed" />
                                    </Style>
                                </ListView.Resources>
                                <ListView.ItemTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding ErrorContent}" />
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                            </ListView>
                        </Border>
                    </StackPanel>
                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding AdornedElement.IsFocused, ElementName=adorner}" Value="False">
                            <Setter TargetName="validationErrorsContainer" Property="Visibility" Value="Collapsed" />
                        </DataTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

ValidatedTextBox.cs

namespace YourNameSpace
{
    public class ValidatedTextBox : TextBox
    {
        static ValidatedTextBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ValidatedTextBox), new FrameworkPropertyMetadata(typeof(ValidatedTextBox)));
        }
    }
}