如何子类化WPF ComboBox以添加额外的按钮

时间:2010-08-18 18:01:58

标签: c# wpf combobox custom-controls

我看到了一个类似的问题,并希望找到一个解决方案,但仅仅提供一个关于ComboBox子类的建议对我来说还不够。我需要用小汤匙......

案例是我在我的特殊组合框上需要一个额外的按钮,用于将新记录添加到项目列表中。我今天将它作为UserControl但它看起来不太好,我需要对视图进行更多控制,所以我开始尝试扩展ComboBox。

我没有走远......请借给我一把...... :)。

到目前为止我的代码:

public class ComboBoxWithAdd : ComboBox
{
    static ComboBoxWithAdd()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(ComboBoxWithAdd), new FrameworkPropertyMetadata(typeof(ComboBoxWithAdd)));
    }
}

在Generic.xaml中我有这个:

<Style TargetType="{x:Type local:ComboBoxWithAdd}" BasedOn="{StaticResource {x:Type ComboBox}}">        
</Style>

3 个答案:

答案 0 :(得分:4)

在决定创建自定义控件时,您需要确定是需要添加实际行为还是仅添加UI。只需添加一个按钮就可以通过自定义ControlTemplate来完成。听起来你想要一个按钮,它会导致一个动作,它将更新ComboBox的项目,这将指向你从ComboBox派生控件的方向。您需要在代码和XAML方面添加一些内容。在你的Style中,你需要为ControlTemplate添加一个Setter,并从ComboBox的默认模板的副本开始(我通常使用Blend执行此操作,但还有其他来源)。然后,您可以在模板中的任何位置添加新按钮。

<Style TargetType="{x:Type local:ComboBoxWithAdd}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:ComboBoxWithAdd}">
                ... copy of default template with your modifications
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

您可以通过几种不同的方式连接按钮,但最强大的方法是使用您可以在控制代码中绑定的命令。您可以稍后在控制代码中声明自己的RoutedCommand,但要开始使用内置的一个。

public ComboBoxWithAdd()
{
    CommandBindings.Add(new CommandBinding(ApplicationCommands.New, NewExecutedMethod));
}

然后在NewExecutedMethod中添加您想要执行实际操作的任何逻辑来添加项目(可能使用ComboBox的Items / ItemsSource)。要连接按钮,只需设置Command="ApplicationCommands.New"即可。使用自定义控件可以完成更多工作,但这应该可以让您入门。

答案 1 :(得分:1)

Rozon,您可以像这样操作后面的代码中的Combobox,而无需创建复杂的模板:

public class CustomComboBox : ComboBox
{
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        Grid grid = WpfHelper.FindAllChildrenByName<Grid>(this, "MainGrid").SingleOrDefault() as Grid;
        if (grid != null)
        {
            grid.ColumnDefinitions.Add(new ColumnDefinition());
            Button button = new Button();
            button.Content = "test";
            button.SetValue(Grid.ColumnProperty, 2);
            grid.Children.Add(button);
        }
    } 
}

WpfHelper只是一个通过名称查找可视子项的类。请注意,如果更改组合框的标准控件模板并重命名MainGrid,则可能会轻易破坏。

答案 2 :(得分:0)

我建议您使用您创建的UserControl,再添加一个按钮并对其进行分组以使用户控制并公开所需的事件和命令。

不建议进行自定义控制。

但是,如果你有这样的要求。开始了: 1)您需要为尝试扩展功能的内容派生控件。 2)您需要为控件创建默认模板。 [Generic.Xaml]

休息是你的定制。 但是,一个优点是你可以轻松获得Skinnable控件。

HTH