【问题标题】:How to trigger the comboBox SelectionChanged Event from a behavior attached to it如何从附加的行为触发组合框 SelectionChanged 事件
【发布时间】:2014-09-14 08:46:10
【问题描述】:

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

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

编辑:

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

编辑 2:

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

不工作的特殊情况(作为 ComboBox 行为的默认设置):当打开未选择的组合之一并且在不更改其选择的情况下关闭它时 - 不会触发任何事件。但是 - 这个组合在我现在想要选择的未选择类别下,因为用户已经选择了它。我的想法是使用行为(在 xaml 代码中,但到目前为止还没有工作......)

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

<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>

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

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

【问题讨论】:

    标签: c# wpf mvvm combobox


    【解决方案1】:

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

    Xaml:

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

    视图模型:

    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 
       }
    

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

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

    参考资料:

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

    Xaml:

    <...
       <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>
    .../>
    

    这会将您的事件连接到一个命令,该命令将在视图模型上执行,并按要求提供参数。

    视图模型:

     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.... 
          }
     }
    

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

    【讨论】:

    • 谢谢,斯蒂安。我正是这样做的。我的问题是在打开组合但不更改选择时的特殊情况。在这种情况下,我想知道组合已打开,并获取所选项目(未更改)。缺少什么,是发生这种情况时的触发器。
    • 如前所述,您拥有 IsDropDownOpen 属性和 DropDownClosed 事件。如果我理解正确的话。将上面代码中的事件替换为该事件,绑定您选择的项目,并检查它是否更改。
    【解决方案2】:

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

    【讨论】:

    • 这正是问题所在……哪种方法?
    • 您用来处理 comboBox.SelectionChanged 事件的方法。
    • 现在我明白你的意思了.. 但它不适合我的项目,因为它是 MVVM 风格,这就是我试图通过一种行为来做到这一点的原因。
    • 感谢 Hamma 的帮助,但您的回答有点模糊......命令是什么意思?
    • 我的回答和你的问题一样模糊,没有代码或任何东西。如果你正在尝试实现 MVVM,你应该看看 Commands。那里有很多教程,只需 google,您就会找到很多材料。命令的简化实现称为 RelayCommand,您也可以查找它。抱歉,我的回答对您来说含糊不清,但这不是找到此类信息的地方;我告诉过你应该使用什么,现在你看看它,试试它,如果你有实现问题,你可以用正确的代码提出问题。这样更容易为您提供帮助。
    猜你喜欢
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 2011-06-28
    • 1970-01-01
    相关资源
    最近更新 更多