目标:在选择了组合框下拉列表中的项目时发出事件。
问题:但是,如果用户选择与当前正在选择的项目相同的项目,则使用“SelectionChanged”,则不会更改选择,因此不会触发此事件。
问题只要鼠标点击该项目并且该项目是,则我可以使用什么其他事件处理程序(或其他方式)来发布事件而不管所选项目是否已更改被选中。
(澄清:问题是当再次选择相同项目时如何触发“某事”。下拉列表中没有重复。场景:第一次选择项目1,关闭下拉列表。然后再次打开下拉列表框,并在触发某些功能时选择项目1。)
解决方案:目前似乎没有直接的解决方案来做到这一点。但根据每个项目,可以有办法解决它。 (如果确实有很好的方法,请更新)。感谢。
答案 0 :(得分:15)
我有同样的问题,我终于找到了答案:
您需要像这样处理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;
}
}
答案 1 :(得分:6)
您可以使用“ComboBoxItem.PreviewMouseDown”事件。因此,每当鼠标停在某个项目上时,此事件将被触发。
要在XAML中添加此事件,请使用“ComboBox.ItemContainerStyle”,如下例所示:
<ComboBox x:Name="MyBox"
ItemsSource="{Binding MyList}"
SelectedValue="{Binding MyItem, Mode=OneWayToSource}" >
<ComboBox.ItemContainerStyle>
<Style>
<EventSetter Event="ComboBoxItem.PreviewMouseDown"
Handler="cmbItem_PreviewMouseDown"/>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
并照常处理
void cmbItem_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
//...do your item selection code here...
}
感谢MSDN
答案 2 :(得分:6)
对我来说ComboBox.DropDownClosed
事件做到了。
private void cbValueType_DropDownClosed(object sender, EventArgs e)
{
if (cbValueType.SelectedIndex == someIntValue) //sel ind already updated
{
// change sel Index of other Combo for example
cbDataType.SelectedIndex = someotherIntValue;
}
}
答案 3 :(得分:5)
我希望您能找到以下技巧。
您可以绑定两个事件
combobox.SelectionChanged += OnSelectionChanged;
combobox.DropDownOpened += OnDropDownOpened;
并在OnDropDownOpened
内强制选中的项为nullprivate void OnDropDownOpened(object sender, EventArgs e)
{
combobox.SelectedItem = null;
}
使用OnSelectionChanged中的项目执行所需操作。 每次打开组合框时都会引发OnSelectionChanged,但是你可以检查方法中的SelectedItem是否为null并跳过命令
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (combobox.SelectedItem != null)
{
//Do something with the selected item
}
}
答案 4 :(得分:2)
对于UWP(Windows应用商店)应用,以上都不会起作用(PointerPressed不会触发;不存在Preview,DropDownClosed或SelectedIndexChanged事件)
我不得不求助于覆盖ComboBox的透明按钮(但不是它的下拉箭头)。当您按下箭头时,列表会像往常一样下降,并且组合框的SelectionChanged事件将触发。当您单击组合框上的任何其他位置时,透明按钮的单击事件将触发,允许您重新选择组合框的当前值。
一些有效的XAML代码:
android:tint
一些有效的C#代码:
<Grid x:Name="ComboOverlay" Margin="0,0,5,0"> <!--See comments in code behind at ClickedComboButValueHasntChanged event handler-->
<ComboBox x:Name="NewFunctionSelect" Width="97" ItemsSource="{x:Bind Functions}"
SelectedItem="{x:Bind ChosenFunction}" SelectionChanged="Function_SelectionChanged"/>
<Button x:Name="OldFunctionClick" Height="30" Width="73" Background="Transparent" Click="ClickedComboButValueHasntChanged"/>
</Grid>
答案 5 :(得分:1)
您可以尝试“SelectedIndexChanged
”,即使选择了相同的项目,它也会触发事件。
答案 6 :(得分:0)
这个问题困扰了我很长一段时间,因为没有一个解决办法为我工作:(
但好消息是,以下方法适用于我的应用程序。
基本想法是在EventManager
注册App.xmal.cs
以嗅PreviewMouseLeftButtonDownEvent
所有ComboBoxItem
,如果选择的项目是SelectionChangedEvent
,则触发App.xmal.cs
与所选项目相同,即在不更改索引的情况下执行选择。
在public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
// raise selection change event even when there's no change in index
EventManager.RegisterClassHandler(typeof(ComboBoxItem), UIElement.PreviewMouseLeftButtonDownEvent,
new MouseButtonEventHandler(ComboBoxSelfSelection), true);
base.OnStartup(e);
}
private static void ComboBoxSelfSelection(object sender, MouseButtonEventArgs e)
{
var item = sender as ComboBoxItem;
if (item == null) return;
// find the combobox where the item resides
var comboBox = ItemsControl.ItemsControlFromItemContainer(item) as ComboBox;
if (comboBox == null) return;
// fire SelectionChangedEvent if two value are the same
if ((string)comboBox.SelectedValue == (string)item.Content)
{
comboBox.IsDropDownOpen = false;
comboBox.RaiseEvent(new SelectionChangedEventArgs(Selector.SelectionChangedEvent, new ListItem(), new ListItem()));
}
}
}
:
SelectionChangedEvent
然后,对于所有组合框,以正常方式注册<ComboBox ItemsSource="{Binding BindList}"
SelectionChanged="YourSelectionChangedEventHandler"/>
:
SelectionChangedEvent
现在,如果两个索引不同,那么普通的事件处理过程没什么特别之处;如果两个索引相同,则首先处理项目上的鼠标事件,从而触发SelectionChangedEvent
。这样,两种情况都会触发{{1}}:)
答案 7 :(得分:0)
这是一个用于附加到ComboBox的DependencyObject。
当打开下拉列表时,它会记录当前选定的项目,如果在关闭下拉列表时仍然选择了相同的索引,则会触发SelectionChanged事件。可能需要对其进行修改才能使用键盘选择。
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Web.UI.WebControls;
namespace MyNamespace
{
public class ComboAlwaysFireSelection : DependencyObject
{
public static readonly DependencyProperty ActiveProperty = DependencyProperty.RegisterAttached(
"Active",
typeof(bool),
typeof(ComboAlwaysFireSelection),
new PropertyMetadata(false, ActivePropertyChanged));
private static void ActivePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var element = d as ComboBox;
if (element == null)
return;
if ((e.NewValue as bool?).GetValueOrDefault(false))
{
element.DropDownClosed += ElementOnDropDownClosed;
element.DropDownOpened += ElementOnDropDownOpened;
}
else
{
element.DropDownClosed -= ElementOnDropDownClosed;
element.DropDownOpened -= ElementOnDropDownOpened;
}
}
private static void ElementOnDropDownOpened(object sender, EventArgs eventArgs)
{
_selectedIndex = ((ComboBox) sender).SelectedIndex;
}
private static int _selectedIndex;
private static void ElementOnDropDownClosed(object sender, EventArgs eventArgs)
{
var comboBox = ((ComboBox) sender);
if (comboBox.SelectedIndex == _selectedIndex)
{
comboBox.RaiseEvent(new SelectionChangedEventArgs(Selector.SelectionChangedEvent, new ListItemCollection(), new ListItemCollection()));
}
}
[AttachedPropertyBrowsableForChildrenAttribute(IncludeDescendants = false)]
[AttachedPropertyBrowsableForType(typeof(ComboBox))]
public static bool GetActive(DependencyObject @object)
{
return (bool)@object.GetValue(ActiveProperty);
}
public static void SetActive(DependencyObject @object, bool value)
{
@object.SetValue(ActiveProperty, value);
}
}
}
并添加名称空间前缀以使其可访问。
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ut="clr-namespace:MyNamespace" ></UserControl>
然后你需要像这样附加它
<ComboBox ut:ComboAlwaysFireSelection.Active="True" />
答案 8 :(得分:0)
使用SelectionChangeCommitted(object sender, EventArgs e)
事件
here
答案 9 :(得分:0)
每个ComboBoxItem实例都有PreviewMouseDown事件。如果您将在每个ComboBoxItem上订阅此事件的自定义处理程序,您将有机会处理下拉列表中的每次单击。
<h1>New Comment</h1>
<form method="post">
Comment: <input type="text" size="128" name="comment" value="{{old('body')}}" /></p>
@if ($errors->has('body'))
<p class="warning">Comment cannot be empty.</p>
@endif
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
{{ csrf_field() }}
</form>
答案 10 :(得分:0)
对于UWP,我尝试了另一种方法。我扩展了ComboBox类,并处理了ComboBox上的SelectionChanged和OnKeyUp事件以及ComboBoxItems上的Tapped事件。如果我在没有先获得SelectionChanged的情况下得到了Tapped事件或Enter键或Space键,那么我知道当前项目已被重新选择,我会做出相应的响应。
class ExtendedComboBox : ComboBox
{
public ExtendedComboBox()
{
SelectionChanged += OnSelectionChanged;
}
protected override void PrepareContainerForItemOverride(Windows.UI.Xaml.DependencyObject element, object item)
{
ComboBoxItem cItem = element as ComboBoxItem;
if (cItem != null)
{
cItem.Tapped += OnItemTapped;
}
base.PrepareContainerForItemOverride(element, item);
}
protected override void OnKeyUp(KeyRoutedEventArgs e)
{
// if the user hits the Enter or Space to select an item, then consider this a "reselect" operation
if ((e.Key == Windows.System.VirtualKey.Space || e.Key == Windows.System.VirtualKey.Enter) && !isSelectionChanged)
{
// handle re-select logic here
}
isSelectionChanged = false;
base.OnKeyUp(e);
}
// track whether or not the ComboBox has received a SelectionChanged notification
// in cases where it has not yet we get a Tapped or KeyUp notification we will want to consider that a "re-select"
bool isSelectionChanged = false;
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
isSelectionChanged = true;
}
private void OnItemTapped(object sender, TappedRoutedEventArgs e)
{
if (!isSelectionChanged)
{
// indicates that an item was re-selected - handle logic here
}
isSelectionChanged = false;
}
}
答案 11 :(得分:0)
很简单,只需添加if(e.AddedItems.Count == 0)返回;在像这样的函数开始时:
private void ComboBox_Symbols_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count == 0)
return;
//Some Other Codes
}