如何创建一个自定义控件,它是一个带有组头的组合框

时间:2013-06-18 04:47:56

标签: wpf combobox custom-controls

我有一个特殊的要求,需要实现一个组合列表的组合框,我可以按以下方式进行操作

XAML文件

<Window x:Class="GroupComboBox.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">
    <Grid>
            <ComboBox x:Name="comboBox" Width="100">

                <ComboBox.Resources>
                    <Style TargetType="{x:Type ComboBox}">
                        <Setter Property="ItemsPanel">
                            <Setter.Value>
                                <ItemsPanelTemplate>
                                    <WrapPanel IsItemsHost="True" Orientation="Horizontal" Width="150" Height="Auto" >
                                        <!-- add scroll bar -->
                                    </WrapPanel>
                                </ItemsPanelTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                    <Style TargetType="{x:Type ComboBoxItem}">
                        <Setter Property="Width" Value="50" />
                    </Style>
                </ComboBox.Resources>

                <ComboBox.GroupStyle>
                    <GroupStyle>
                        <GroupStyle.HeaderTemplate>
                            <DataTemplate>
                                <Border BorderBrush="Black" BorderThickness="2">
                                <TextBlock Text="{Binding Name}" HorizontalAlignment="Stretch" Background="YellowGreen"/>
                                </Border>
                            </DataTemplate>
                        </GroupStyle.HeaderTemplate>
                    </GroupStyle>
                </ComboBox.GroupStyle>

                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Item}" Width="40"/>
                    </DataTemplate>
                </ComboBox.ItemTemplate>



                <ComboBox.ItemContainerStyle>
                    <Style TargetType="{x:Type ComboBoxItem}">
                        <Setter Property="IsEnabled" Value="{Binding Available}"/>
                    </Style>
                </ComboBox.ItemContainerStyle>
            </ComboBox>

    </Grid>
</Window>

代码隐藏文件

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            List<CategoryItem<string>> items = new List<CategoryItem<string>>();

            for (int i = 0; i < 18; ++i)
            {
                items.Add(new CategoryItem<string> { Item = string.Format("{0:D2}", i), Available = (i > 9), Category = "Group A" });
            }

            for (int i = 0; i < 4; ++i)
            {
                items.Add(new CategoryItem<string> { Item = string.Format("{0:D2}", i), Available = (i > 2), Category = "Group B" });
            }

            //Need the list to be ordered by the category or you might get repeating categories
            ListCollectionView lcv = new ListCollectionView(items.OrderBy(w => w.Category).ToList());

            //Create a group description
            lcv.GroupDescriptions.Add(new PropertyGroupDescription("Category"));

            this.comboBox.ItemsSource = lcv;

        }   

    }

    public class CategoryItem<T>
    {
        public T Item { get; set; }
        public bool Available { get; set; }
        public string Category { get; set; }
    }

现在我想让组合框成为一个自定义控件,然后它可以很容易地重复使用,但我是创建自定义控件的新手,我该怎么办?

目前我已经创建了一个WPF自定义控件库,并将自定义控件的基类更改为'ComboBox',但我不知道如何正确地将样式和模板移动到资源字典文件

1 个答案:

答案 0 :(得分:0)

我可以提供以下变体。移动资源中的所有样式和模板:

<!-- Main style for ComboBox -->
<Style x:Key="MyComboBox" TargetType="{x:Type ComboBox}">
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="Width" Value="100" />
    <Setter Property="Height" Value="25" />

    <Setter Property="ItemsPanel">
        <Setter.Value>
             <ItemsPanelTemplate>
                 <WrapPanel IsItemsHost="True" Orientation="Horizontal" Width="150" Height="Auto" />
             </ItemsPanelTemplate>
        </Setter.Value>
     </Setter>

     <Setter Property="ItemTemplate">
         <Setter.Value>
             <DataTemplate>
                 <TextBlock Text="{Binding Item}" Width="40"/>
             </DataTemplate>
         </Setter.Value>
     </Setter>            
</Style>

<!-- Style for ComboBoxItem -->
<Style TargetType="{x:Type ComboBoxItem}">
    <Setter Property="Width" Value="50" />
</Style>

<!-- Style for ItemContainerStyle -->
<Style x:Key="ComboBoxItemContainerStyle" TargetType="{x:Type ComboBoxItem}">
    <Setter Property="IsEnabled" Value="{Binding Available}" />
</Style>

<!-- DataTemplate for HeaderTemplate -->
<DataTemplate x:Key="MyHeaderTemplate">
    <Border BorderBrush="Black" BorderThickness="2">
        <TextBlock Text="{Binding Name}" HorizontalAlignment="Stretch" Background="YellowGreen" />
    </Border>
</DataTemplate>

使用ComboBox和我们的风格:

<ComboBox x:Name="MyComboBox1" Style="{StaticResource MyComboBox}" IsSynchronizedWithCurrentItem="False" ItemContainerStyle="{StaticResource ComboBoxItemContainerStyle}">
    <ComboBox.GroupStyle>
        <GroupStyle HeaderTemplate="{StaticResource MyHeaderTemplate}" />
    </ComboBox.GroupStyle>
</ComboBox>

<ComboBox x:Name="MyComboBox2" Style="{StaticResource MyComboBox}" IsSynchronizedWithCurrentItem="False" ItemContainerStyle="{StaticResource ComboBoxItemContainerStyle}">
    <ComboBox.GroupStyle>
        <GroupStyle HeaderTemplate="{StaticResource MyHeaderTemplate}" />
    </ComboBox.GroupStyle>
</ComboBox>

并在代码中设置数据:

this.MyComboBox1.ItemsSource = lcv;
this.MyComboBox2.ItemsSource = lcv; 

设置您控制的样式需要更改键入并编写您的控件名称:

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

</Style>