Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF SelectionChanged to same value

Tags:

c#

wpf

xaml

I am using SelectionChanged in ComboBox item, but when I select the same item again the SelectionChanged function does not fire and I need it to do so. How can I tell it to fire no mater witch selection I do.

private void ComboBox_SelectionChanged4(object sender, SelectionChangedEventArgs e)
    {

      //do some stuff

    }

XAML:

<ComboBox   Height="30" Name="Combo4" Style="{StaticResource CategoryComboBox}"   SelectionChanged="ComboBox_SelectionChanged4" Grid.ColumnSpan="2"  Grid.Column="0">
            <ComboBoxItem Content="ComboBox Item 1 (Example)" />
            <ComboBoxItem Content="ComboBox Item 2 (Example)" />
            <ComboBoxItem Content="ComboBox Item 3 (Example)" />
            <ComboBoxItem Content="ComboBox Item 4 (Example)" />
        </ComboBox>

Adding items:

for (int i = 0; i < Pr4.Count(); i++)
        {
            ComboBoxItem item = new ComboBoxItem();
            item.Content = Pr4[i];
            Combo4.Items.Add(item);

        }
like image 774
Dim Avatar asked Mar 06 '14 12:03

Dim


3 Answers

I used DropDownClosed, thank to - Clemens

like image 137
Dim Avatar answered Sep 22 '22 05:09

Dim


I had the same question and I finally found the answer:

You need to handle BOTH the SelectionChanged event and the DropDownClosed like this:

In XAML:

<ComboBox Name="cmbSelect" SelectionChanged="ComboBox_SelectionChanged" DropDownClosed="ComboBox_DropDownClosed">
  <ComboBoxItem>1</ComboBoxItem>
  <ComboBoxItem>2</ComboBoxItem>
  <ComboBoxItem>3</ComboBoxItem>
</ComboBox>

In C#:

private bool handle = true;
private void ComboBox_DropDownClosed(object sender, EventArgs e) {
  if(handle)Handle();
  handle = true;
}

private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
  ComboBox cmb = sender as ComboBox;
  handle = !cmb.IsDropDownOpen;
  Handle();
}

private void Handle() {
  switch (cmbSelect.SelectedItem.ToString().Split(new string[] { ": " }, StringSplitOptions.None).Last())
  { 
      case "1":
          //Handle for the first combobox
          break;
      case "2":
          //Handle for the second combobox
          break;
      case "3":
          //Handle for the third combobox
          break;
  }
}
like image 22
deltonio2 Avatar answered Sep 21 '22 05:09

deltonio2


Behavior which uses DropDownOpen and DropDwonClose

public class InvokeIfSameElementSelectedBehavior : Behavior<ComboBox>
    {
        #region public ICommand Command

        private static readonly PropertyMetadata CommandMetaData = new PropertyMetadata(default(ICommand));

        public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command",
            typeof(ICommand), typeof(InvokeIfSameElementSelectedBehavior), CommandMetaData);

        public ICommand Command
        {
            get { return (ICommand)GetValue(CommandProperty); }
            set { SetValue(CommandProperty, value); }
        }

        #endregion //public ICommand Command

        private bool _skipSelectionChanged;
        private bool _popupMouseClicked;
        private Popup _popup;
        private object _previousValue;

        protected override void OnAttached()
        {
            base.OnAttached();

            if(AssociatedObject.IsLoaded)
                AttachAllEvents();
            else 
                AssociatedObject.Loaded += AssociatedObjectOnLoaded;
        }

        private void AssociatedObjectOnLoaded(object sender, RoutedEventArgs routedEventArgs)
        {
            AssociatedObject.Loaded -= AssociatedObjectOnLoaded;
            AttachAllEvents();
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.SelectionChanged -= AssociatedObjectOnSelectionChanged;
            AssociatedObject.DropDownOpened -= AssociatedObjectOnDropDownOpened;
            AssociatedObject.DropDownClosed -= AssociatedObjectOnDropDownClosed;

            if(_popup != null)
                _popup.PreviewMouseLeftButtonDown -= PopupOnPreviewMouseLeftButtonDown;
        }

        private void AttachAllEvents()
        {
            AssociatedObject.SelectionChanged += AssociatedObjectOnSelectionChanged;
            AssociatedObject.DropDownOpened += AssociatedObjectOnDropDownOpened;
            AssociatedObject.DropDownClosed += AssociatedObjectOnDropDownClosed;

            AssociatedObject.ApplyTemplate();
            _popup = (Popup)AssociatedObject.Template.FindName("PART_Popup", AssociatedObject);
            if(_popup != null)
                _popup.PreviewMouseLeftButtonDown += PopupOnPreviewMouseLeftButtonDown;
        }

        private void AssociatedObjectOnDropDownOpened(object sender, EventArgs e)
        {
            _popupMouseClicked = false;
            _previousValue = AssociatedObject.SelectedItem;
        }

        private void AssociatedObjectOnDropDownClosed(object sender, EventArgs e)
        {
            try
            {
                if (_popupMouseClicked && Equals(AssociatedObject.SelectedItem, _previousValue)) //SelectionChanged handles it if value are not the same
                    InvokeChangeCommand(AssociatedObject.SelectedItem);
            }
            finally
            {
                _popupMouseClicked = false;
            }
        }

        private void PopupOnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            //ignore clicks on the scrollbars
            if(e.Source is ScrollViewer)
                return;

            _popupMouseClicked = true;
        }

        private void AssociatedObjectOnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (_skipSelectionChanged)
                return;

            try
            {
                _skipSelectionChanged = true;

                if (e.AddedItems.Count != 1)
                    return;
                InvokeChangeCommand(e.AddedItems[0]);
            }
            finally
            {
                _skipSelectionChanged = false;
            }
        }

        private void InvokeChangeCommand(object item)
        {
            if (Command == null)
                return;

            if (!Command.CanExecute(item))
                return;

            Command.Execute(item);
        }
    }

Sample:

<ComboBox>
    <i:Interaction.Behaviors>
        <behaviors:InvokeIfSameElementSelectedBehavior Command="{Binding SelectionChangedCommand}"/>
    </i:Interaction.Behaviors>
</ComboBox>
like image 28
aderesh Avatar answered Sep 22 '22 05:09

aderesh