【问题标题】:WPF SelectionChanged to same valueWPF 选择更改为相同的值
【发布时间】:2015-03-18 17:49:58
【问题描述】:

我在 ComboBox 项目中使用了 SelectionChanged,但是当我再次选择同一个项目时,SelectionChanged 函数不会触发,我需要它来执行此操作。无论我选择什么女巫,我怎么能告诉它解雇。

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>

添加项目:

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

        }

【问题讨论】:

  • 您能否显示一些代码 - 即,您的视图模型中的属性是什么样的(您是否使用视图模型)等。另外请显示您的 xaml。
  • It doesn't make sense to fire a SelectionChanged event when the selection hasn't actually changed.然而,还有其他事件,例如DropDownClosed.
  • 在内部,如果选择实际更改,ComboBox 只会引发 SelectionChanged 事件,这就是您看不到该事件的原因。正如 Clemens 所说,如果您想记录不是所选项目更改的内容,请使用不同的事件并自己处理。一种可能性可能是在 DropDownOpen 上将所选项目设置为 null,以便在选择某些内容时获得 SelectedItem 更改。
  • Clemens - 请将其发布为答案。 DropDownClosed 工作
  • 即使它没有改变,解雇它也很有意义。例如。如果您对组使用相同的组合框,而且对组的项目也使用相同的组合框。

标签: c# wpf xaml


【解决方案1】:

我使用了 DropDownClosed,感谢 - Clemens

【讨论】:

    【解决方案2】:

    我有同样的question,我终于找到了答案:

    您需要像这样处理 SelectionChanged 事件和 DropDownClosed:

    在 XAML 中:

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

    在 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;
      }
    }
    

    【讨论】:

      【解决方案3】:

      使用 DropDownOpen 和 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);
              }
          }
      

      示例:

      <ComboBox>
          <i:Interaction.Behaviors>
              <behaviors:InvokeIfSameElementSelectedBehavior Command="{Binding SelectionChangedCommand}"/>
          </i:Interaction.Behaviors>
      </ComboBox>
      

      【讨论】:

        【解决方案4】:

        您甚至可以使用打开的下拉菜单将选择设置为 -1。然后在事件处理程序中,您需要忽略该更改。在下拉关闭事件中,如果控件关闭,您可以恢复原始值。(也忽略此更改)

        【讨论】:

          【解决方案5】:

          您可以将事件处理程序绑定到组合框的onclickevent,然后检查所选项目是否为空

          【讨论】:

            【解决方案6】:

            要做到这一点,您必须为您在组合框中添加的每个项目添加一个鼠标向上事件。

            【讨论】:

              猜你喜欢
              • 2013-03-05
              • 2013-03-03
              • 1970-01-01
              • 1970-01-01
              • 2011-12-06
              • 2011-10-23
              • 1970-01-01
              • 1970-01-01
              • 2011-10-14
              相关资源
              最近更新 更多