Wpf 如何为自定义控件设置GroupStyle

Wpf 如何为自定义控件设置GroupStyle,wpf,custom-controls,resourcedictionary,Wpf,Custom Controls,Resourcedictionary,我创建了一个自定义控件库项目,并执行了以下操作: 自定义控件派生自ComboBox 在主题文件夹下添加资源字典文件rd.xaml 在rd.xaml文件中定义一些样式 <Style x:Key="GroupComboBoxStyle" TargetType="{x:Type local:GroupComboBox}"> <Setter Property="ItemContainerStyle" > <Setter.Value>

我创建了一个自定义控件库项目,并执行了以下操作:

  • 自定义控件派生自ComboBox
  • 在主题文件夹下添加资源字典文件rd.xaml
  • 在rd.xaml文件中定义一些样式

    <Style x:Key="GroupComboBoxStyle" TargetType="{x:Type local:GroupComboBox}">
    
        <Setter Property="ItemContainerStyle" >
            <Setter.Value>
                <Style TargetType="{x:Type ComboBoxItem}">
                    <Setter Property="IsEnabled" Value="{Binding Available}"/>
                </Style>
            </Setter.Value>
        </Setter>
    
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:GroupComboBox}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
    
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    
    
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <WrapPanel IsItemsHost="True" Orientation="Horizontal" Width="150" Height="Auto" >
                        <!-- add scroll bar -->
                    </WrapPanel>
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
    
        <Setter Property="ItemTemplate">
            <Setter.Value>
                <DataTemplate>
                    <TextBlock Text="{Binding Item}" Width="40"/>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    
    </Style>
    
    <CollectionViewSource x:Key="groupedData" Source="{Binding Items}">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="Category"/>
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
    
    <Style x:Key="groupComboBoxItemStyle" TargetType="{x:Type ComboBoxItem}">
        <Setter Property="Width" Value="50" />
    </Style>
    
    <GroupStyle x:Key="groupStyle">
        <GroupStyle.HeaderTemplate>
            <DataTemplate>
                <Border BorderBrush="Black" BorderThickness="2">
                    <TextBlock Text="{Binding Name}" HorizontalAlignment="Stretch" Background="YellowGreen"/>
                </Border>
            </DataTemplate>
        </GroupStyle.HeaderTemplate>
    </GroupStyle>
    


    WPF CustomControl应该是无外观的。这意味着,代码应该只包含控件的逻辑,而与它的外观、样式等无关。这一切都应该使用Generic.xaml中为您创建的样式来完成


    无论如何,它是完全有效的希望在您的标题绿色背景。。。我建议为控件中的
    DefaultGroupStyle
    创建一个可绑定的依赖项属性。我已经实现并测试了它,它做到了:

    控件
    GroupComboBox

    public class GroupComboBox : ComboBox
    {
        public static readonly DependencyProperty DefaultGroupStyleProperty =
            DependencyProperty.Register("DefaultGroupStyle", typeof (GroupStyle), typeof (GroupComboBox), new PropertyMetadata(default(GroupStyle), OnDefaultGroupStyleChanged));
    
        private static void OnDefaultGroupStyleChanged(DependencyObject s, DependencyPropertyChangedEventArgs a)
        {
            var c = (GroupComboBox) s;
            if (a.NewValue == null) return;
    
            if (c.GroupStyle.Count == 0)
                c.GroupStyle.Add((GroupStyle) a.NewValue);
        }
    
        public GroupStyle DefaultGroupStyle
        {
            get { return (GroupStyle) GetValue(DefaultGroupStyleProperty); }
            set { SetValue(DefaultGroupStyleProperty, value); }
        }
    
        static GroupComboBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(GroupComboBox), new FrameworkPropertyMetadata(typeof(GroupComboBox)));
        }
    }
    
    和Generic.xaml中的样式(可以随意将样式移动到另一个文件中,但不要忘记将其合并到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:WpfCustomControlLibrary1">
    
        <GroupStyle x:Key="GroupStyle">
            <GroupStyle.HeaderTemplate>
                <DataTemplate>
                    <Border BorderBrush="Black" BorderThickness="2">
                        <TextBlock Text="{Binding Name}" HorizontalAlignment="Stretch" Background="YellowGreen"/>
                    </Border>
                </DataTemplate>
            </GroupStyle.HeaderTemplate>
        </GroupStyle>
    
        <Style TargetType="{x:Type local:GroupComboBox}">
    
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:GroupComboBox}">
                        <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
    
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
    
            <Setter Property="DefaultGroupStyle" Value="{StaticResource GroupStyle}" />
    
        </Style>
    </ResourceDictionary>
    
    
    

    请让我知道这是否适用于您,如果有任何不清楚的地方,请随时询问。

    WPF CustomControl应该是无外观的。这意味着,代码应该只包含控件的逻辑,而与它的外观、样式等无关。这都应该使用为您创建的样式来完成n Generic.xaml


    无论如何,希望标题中有绿色背景是完全正确的…我建议为控件中的
    DefaultGroupStyle
    创建一个可绑定的依赖项属性。我已经实现并测试了它,它实现了以下技巧:

    控件
    GroupComboBox

    public class GroupComboBox : ComboBox
    {
        public static readonly DependencyProperty DefaultGroupStyleProperty =
            DependencyProperty.Register("DefaultGroupStyle", typeof (GroupStyle), typeof (GroupComboBox), new PropertyMetadata(default(GroupStyle), OnDefaultGroupStyleChanged));
    
        private static void OnDefaultGroupStyleChanged(DependencyObject s, DependencyPropertyChangedEventArgs a)
        {
            var c = (GroupComboBox) s;
            if (a.NewValue == null) return;
    
            if (c.GroupStyle.Count == 0)
                c.GroupStyle.Add((GroupStyle) a.NewValue);
        }
    
        public GroupStyle DefaultGroupStyle
        {
            get { return (GroupStyle) GetValue(DefaultGroupStyleProperty); }
            set { SetValue(DefaultGroupStyleProperty, value); }
        }
    
        static GroupComboBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(GroupComboBox), new FrameworkPropertyMetadata(typeof(GroupComboBox)));
        }
    }
    
    和Generic.xaml中的样式(可以随意将样式移动到另一个文件中,但不要忘记将其合并到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:WpfCustomControlLibrary1">
    
        <GroupStyle x:Key="GroupStyle">
            <GroupStyle.HeaderTemplate>
                <DataTemplate>
                    <Border BorderBrush="Black" BorderThickness="2">
                        <TextBlock Text="{Binding Name}" HorizontalAlignment="Stretch" Background="YellowGreen"/>
                    </Border>
                </DataTemplate>
            </GroupStyle.HeaderTemplate>
        </GroupStyle>
    
        <Style TargetType="{x:Type local:GroupComboBox}">
    
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:GroupComboBox}">
                        <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
    
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
    
            <Setter Property="DefaultGroupStyle" Value="{StaticResource GroupStyle}" />
    
        </Style>
    </ResourceDictionary>
    
    
    

    请让我知道这是否适用于您,如果有任何不清楚的地方,请随时询问。

    如何处理GroupComboxItemStyle?我不知道您想用它做什么…只需像在其他任何地方一样使用它。当我尝试将自定义控件用于另一个wpf应用程序项目时,出现以下错误:------------E错误对话框-----------------无法将类型为“MS.Internal.NamedObject”的对象强制转换为类型为“System.Windows.Controls.GroupStyle”。“无法将类型为“MS.Internal.NamedObject”的对象强制转换为类型为“System.Windows.Controls.GroupStyle”。”------------------------------------好-----------------我已经按照上面的方式实现和测试了它,它工作了,样式正在应用。因此,请制作一个演示项目,使用我所展示的内容,尝试它是否工作,如果不工作,请随意上传演示。如何处理GroupComboxItemStyle?我不知道你想用它做什么必须像在其他任何地方一样使用它。当我尝试将自定义控件用于另一个wpf应用程序项目时,出现以下错误:------------错误对话框-----------------无法将“MS.Internal.NamedObject”类型的对象强制转换为“System.Windows.Controls.GroupStyle”类型。无法将“MS.Internal.NamedObject”类型的对象强制转换为“System.Windows.Controls.GroupStyle”类型。“------------------------------------好-----------------我已经按照上面的方式实现并测试了它,它可以工作,风格正在应用。因此,请制作一个演示项目,用我所展示的内容,尝试它是否工作,如果不工作,请随意上传演示。