wpf 如何从附加到它的行为触发组合框 SelectionChanged 事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24905875/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:12:03  来源:igfitidea点击:

How to trigger the comboBox SelectionChanged Event from a behavior attached to it

c#wpfmvvmcombobox

提问by Keren

I have some ComboBoxcontrols, each with some values. Each selected value triggers one of my events. When item selected from ComboBoxA, my event is triggerd with the value of the selected item. When one of my combo boxes is just opened and closed, no value changed in it, the event is not triggerd (this is the default behaviour of a combobox). But this is not what i need.

我有一些ComboBox控件,每个控件都有一些值。每个选定的值都会触发我的一个事件。当从 ComboBoxA 中选择 item 时,我的事件将使用所选 item 的值触发。当我的一个组合框刚刚打开和关闭时,其中没有任何值更改,则不会触发该事件(这是组合框的默认行为)。但这不是我需要的。

What i did, is to create a behavior that will associate with the DropDownClosedevent, but i don't know how to trigger the SelectionChangedevent.

我所做的是创建一个与DropDownClosed事件相关联的行为,但我不知道如何触发SelectionChanged事件。

Edit:

编辑:

This question can be generalized: How to 'manually' trigger an event of a UI control? or - Is there a way to invoke the methods assosiated with an event?

这个问题可以概括为:如何“手动”触发 UI 控件的事件?或者 - 有没有办法调用与事件相关的方法?

Edit 2:

编辑2:

I'll try to explain the problem more clearly. I have this code, which takes a list of items, and present them as categories (Radio button) and items under category (ComboBox inside RadioButton). When selecting an item - the selection changed event is triggerd. OK! when selecting another radio button - an event is triggered. OK!!

我会尽量更清楚地解释这个问题。我有这个代码,它需要一个项目列表,并将它们显示为类别(单选按钮)和类别下的项目(单选按钮内的组合框)。选择项目时 - 触发选择更改事件。好的!选择另一个单选按钮时 - 触发事件。好的!!

Special case that not work (as default for ComboBox behavior): when opening one of the combo that is not selected and than closing it without changing its selection - no event is triggered. BUT - this combo is under a not selected category that i want to be selected now, sincr the user thouched it. My idea was to use behavior (is in xaml code, but so far is not working...)

不起作用的特殊情况(作为组合框行为的默认值):当打开未选择的组合之一,而不是在不更改其选择的情况下关闭它时 - 不会触发任何事件。但是 - 这个组合属于我现在想选择的未选择类别,因为用户触摸了它。我的想法是使用行为(在 xaml 代码中,但到目前为止不起作用......)

The code (more or less...):

代码(或多或少......):

<ListBox ItemsSource="{Binding Categories}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Vertical">
                    <RadioButton Content="{Binding CategotyName}" GroupName="TestCategory" IsChecked="{Binding IsSelected}"
                                 cal:Message.Attach="SelectionChanged($dataContext)]"/>
                    <ComboBox cal:Message.Attach="SelectionChanged($dataContext)]" 
                              ItemsSource="{Binding TestsNamesUnderCategory}" SelectedIndex="{Binding SelectedTestInx, Mode=TwoWay}">
                        <i:Interaction.Behaviors>
                            <local:ComboBoxReSelectionBehavior />
                        </i:Interaction.Behaviors>
                    </ComboBox>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

the line cal:Message.Attach="SelectionChanged($dataContext)]"is using Caliburn framework, it just send the trigger to my method.

该行cal:Message.Attach="SelectionChanged($dataContext)]"使用的是 Caliburn 框架,它只是将触发器发送到我的方法。

Hope this is more clear now. Thanks!

希望现在更清楚了。谢谢!

回答by Stígandr

Why are you not just binding the selection to your viewmodels properties, and then do whatever logic that is required there?

为什么您不只是将选择绑定到您的视图模型属性,然后执行那里所需的任何逻辑?

Xaml:

Xml:

<...
   <ComboBox ItemsSource={Binding YourSource} SelectedItem={Binding YourSelectedItem}/>
.../>

ViewModel:

视图模型:

private string yourItem; // assuming we are just dealing with strings...
public String YourItem {
   get { return yourItem; }
   set {
          if( String.Equals(yourItem, value, StringComparison.OrdinalIgnoreCase) )
             return;

          OnYourItemChanged(); // Do your logics here
          RaisePropertyChanged("YourItem");
        }
   }

   private void OnYourItemChanged()
   {
       // .. do stuff here 
   }

If you absolutely need to use events use event-to-command instead...

如果您绝对需要使用事件,请改用事件到命令...

Assuming you are using System.Windows.Interactivity & Galasoft MVVM light

假设您正在使用 System.Windows.Interactivity & Galasoft MVVM light

References:

参考:

 xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"      
 xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"

Xaml:

Xml:

<...
   <ComboBox ItemsSource={Binding YourSource} SelectedItem={Binding YourSelectedItem}>
       <i:Interaction.Triggers>
           <i:EventTrigger EventName="SelectionChanged">
               <cmd:EventToCommand Command="{Binding SomeCommand}" PassEventArgsToCommand="True" />
    </i:EventTrigger>
</i:Interaction.Triggers>
   </ComboBox>
.../>

This will hook your event up to a command, which will be executed on the viewmodel with parameters as requested.

这会将您的事件与命令挂钩,该命令将在视图模型上根据请求使用参数执行。

ViewModel:

视图模型:

 public class YourViewModel : ViewModelBase 
 {
      public ICommand SomeCommand { get; set; }

      public YourViewModel(......)
      {
          SomeCommand = new RelayCommand<SelectionChangedEventArgs>(YourCommandMethod);
      }

      private void YourCommandMethod(SelectionChangedEventArgs e)
      {
          // Do your magic here.... 
      }
 }

Note I wrote this without any access to vs on this computer... There are plenty of examples on how to do this. Hope it helps.

注意我在这台计算机上没有任何访问 vs 权限的情况下写了这个......有很多关于如何做到这一点的例子。希望能帮助到你。

回答by Hamma

If you just need to trigger the event you can call the method from a command activated by DropDownClosed.

如果您只需要触发事件,您可以从 DropDownClosed 激活的命令调用该方法。