Microsoft Developer Network > Página Inicial dos Fóruns > Windows Presentation Foundation (WPF) > I’d like to build a Custom Split Button – strange dropdown behavior..
Fazer uma PerguntaFazer uma Pergunta
 

PerguntaI’d like to build a Custom Split Button – strange dropdown behavior..

  • quarta-feira, 4 de novembro de 2009 14:284breeze Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     Contém Código
    Hello guys,

    I’d like to build an easy Split Button. The problem that I have is that the selected item in the Button disappears when I press the dropdown arrow button on the right site.


    Maybe you can have a look at the code:

    public class PTMSplitButton : Control
        {
    
            #region Constants
            /// <summary>
            /// Constant for the ComboBox element in the SplitButton control.
            /// </summary>
            private const string ElementComboBox = "PART_ComboBox";
            /// <summary>
            /// Constant for the Button element in the SplitButton control.
            /// </summary>
            private const string ElementButton = "PART_Button";
            /// <summary>
            /// Constant for the ContentPresenter element in the SplitButton control.
            /// </summary>
            private const string ElementContentPresenter = "PART_Content";
            #endregion
    
    
            #region Data
            private Selector _dropDown = null;
            private ButtonBase _button = null;
            private ContentPresenter _contentPresenter = null;
            private List<SplitButtonItem> _splitButtonItems = null;
            private object _content = null;
            #endregion
    
            static PTMSplitButton()
            {
                // Provide a default set of visuals for a custom control
                DefaultStyleKeyProperty.OverrideMetadata(typeof(PTMSplitButton), new FrameworkPropertyMetadata(typeof(PTMSplitButton)));
            }
    
    
            #region Items
            /// <summary>
            /// Gets an object representing the collection of the items contained in the items control.
            /// </summary>
            [Category("Common Properties")]
            [Description(" A list to display when the item is clicked.")]
            public List<SplitButtonItem> Items
            {
                get
                {
                    if (_splitButtonItems == null)
                    {
                        _splitButtonItems = new List<SplitButtonItem>();
                    }
    
                    return _splitButtonItems;
                }
            }
            #endregion
    
    
    
            #region SelectionBoxItem
            /// <summary>
            /// Gets the item that is displayed in the selection box. This is a dependency property.
            /// </summary>
            [ReadOnly(true)]
            public object SelectionBoxItem
            {
                get { return GetValue(SelectionBoxItemProperty); }
                private set { SetValue(SelectionBoxItemProperty, value); }
            }
    
            /// <summary>
            /// Identifies the SelectionBoxItem dependency property.
            /// </summary>
            public static readonly DependencyProperty SelectionBoxItemProperty =
                DependencyProperty.Register(
                "SelectionBoxItem",
                typeof(object),
                typeof(PTMSplitButton));
            #endregion
    
    
    
            #region Content
            /// <summary>
            /// Gets or sets the data used to generate the child elements of a System.Windows.Controls.ContentPresenter.
            /// This is a dependency property.
            /// </summary>
            [Description("The Content property of this element can be set to any arbritary value (including simple string values.")]
            [Category("Common Properties")]
            private object Content
            {
                get { return GetValue(ContentProperty); }
                set { SetValue(ContentProperty, value); }
            }
    
            /// <summary>
            /// Identifies the Content dependency property.
            /// </summary>
            private static readonly DependencyProperty ContentProperty =
                DependencyProperty.Register(
                "Content",
                typeof(object),
                typeof(PTMSplitButton),
                new PropertyMetadata(null, OnContentPropertyChanged));
    
            /// <summary>
            /// ContentProperty property changed handler.
            /// </summary>
            /// <param name="d">SplitButton that changed its Content.</param>
            /// <param name="e">DependencyPropertyChangedEventArgs.</param>
            private static void OnContentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                PTMSplitButton sb = d as PTMSplitButton;
                object content = e.NewValue;
    
                if (sb.Content != null)
                {
                    if (sb._contentPresenter == null)
                        return;
    
                    if (sb.Items.Count > 0)
                    {
                        sb._contentPresenter.Content = (sb.SelectionBoxItem as SplitButtonItem).Content;
                    }
                    else
                    {
                        sb._contentPresenter.Content = content;
                    }
                }
                else
                {
                    sb._content = content;
                }
            }
            #endregion
    
    
            public override void OnApplyTemplate()
            {
                base.OnApplyTemplate();
    
                _dropDown = GetTemplateChild(PTMSplitButton.ElementComboBox) as Selector;
                _button = GetTemplateChild(PTMSplitButton.ElementButton) as ButtonBase;
                _contentPresenter = GetTemplateChild(PTMSplitButton.ElementContentPresenter) as ContentPresenter;
    
                if (_dropDown != null)
                {
                    _dropDown.SelectionChanged += new SelectionChangedEventHandler(DropDown_SelectionChanged);
    
                    if (_dropDown.Items.Count == 0)
                    {
                        _dropDown.ItemsSource = Items;
                    }
                }
                if (_contentPresenter != null)
                {
                    _contentPresenter.Content = Content;
                }
    
                if (_button != null)
                {
                    _button.Click += new RoutedEventHandler(Button_Click);
                }
            }
    
    
            #region DropDown_SelectionChanged
            /// <summary>
            /// Event handler for when there is a change in the selection of the SplitButton.
            /// </summary>
            private void DropDown_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                SelectionBoxItem = _dropDown.SelectedItem;
    
                // Set the content of the SplitButton to what was selected
                Content = (_dropDown.SelectedItem as SplitButtonItem).Content;
            }
            #endregion
        }
    

            <controls:PTMSplitButton x:Name="splitButton1" Width="150" Height="42">
                <controls:SplitButtonItem>
                    <Image Source="Images/CallStart_32x32.png" Width="32" Height="32"></Image>
                </controls:SplitButtonItem>
                <controls:SplitButtonItem>one test</controls:SplitButtonItem>
            </controls:PTMSplitButton>
    
    

    Download Solution: PTMSplitButton.zip


    Thanks a lot!


    best regards
    george

    Resources:
    http://wpfsplitbutton.codeplex.com/

Todas as Respostas

  • terça-feira, 10 de novembro de 2009 11:23Jim Zhou - MSFTModeradorMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     
    Hi,
    -->I’d like to build an easy Split Button. The problem that I have is that the selected item in the Button disappears when I press the dropdown arrow button on the right site.

    I tried your code and saw that the program behaved normally, so could you please demonstrate it in detail and what you are trying to do?

    Thanks.
    Sincerely.
    Jim Zhou -MSFT
  • quarta-feira, 11 de novembro de 2009 19:344breeze Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     Contém Código
    Hi Jim Zhou!

    When you open this sample application a dropdown-Button appears. When you click on the arrow at the right side, the green image disappears at the Button. (of course, the green image is in the dropdown-List but it should also stay at the Button)

    That is my desired behavior.


    edit:
    The weird thing at this sample is, if you replace the image with words like this:
    <controls:PTMSplitButton x:Name="splitButton1" Width="150" Height="42">
                <controls:SplitButtonItem>words instead an image</controls:SplitButtonItem>
                <controls:SplitButtonItem>a test</controls:SplitButtonItem>
            </controls:PTMSplitButton>
    
    
    the content (words) does not disappear.

  • quarta-feira, 18 de novembro de 2009 6:334breeze Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     
    Hello, can anyone help me please?