C# 用于所选组合框项的事件处理程序(所选项不必更改)
目标:选择组合框下拉列表中的项目时发出事件 问题:使用“SelectionChanged”,但是,如果用户选择与当前正在选择的项目相同的项目,则不会更改选择,因此不会触发此事件 问题:无论所选项目是否更改,只要鼠标单击该项目且该项目处于选中状态,我都可以使用哪些其他事件处理程序(或其他方式)来发出事件 (澄清:问题是如何在再次选择同一项时触发“某物”。下拉列表中没有重复项。场景:第一次选择项1,关闭下拉列表。然后再次打开下拉框,在触发某些功能时选择项1。) 解决方案:目前似乎没有直接的解决方案。但根据每个单独的项目,都有办法解决它。(如果确实有好的方法,请更新)。谢谢。您可以尝试“C# 用于所选组合框项的事件处理程序(所选项不必更改),c#,wpf,C#,Wpf,目标:选择组合框下拉列表中的项目时发出事件 问题:使用“SelectionChanged”,但是,如果用户选择与当前正在选择的项目相同的项目,则不会更改选择,因此不会触发此事件 问题:无论所选项目是否更改,只要鼠标单击该项目且该项目处于选中状态,我都可以使用哪些其他事件处理程序(或其他方式)来发出事件 (澄清:问题是如何在再次选择同一项时触发“某物”。下拉列表中没有重复项。场景:第一次选择项1,关闭下拉列表。然后再次打开下拉框,在触发某些功能时选择项1。) 解决方案:目前似乎没有直接的解决方案。
SelectedIndexChanged
”,即使选择了相同的项目,它也会触发事件。您可以使用“ComboBoxItem.PreviewMouseDown”事件。因此,每次鼠标落在某个项目上时,都会触发此事件
要在XAML中添加此事件,请使用“ComboBox.ItemContainerStyle”,如下一个示例所示:
照常处理
void cmbItem_PreviewMouseDown(对象发送器,鼠标按钮ventargs e)
{
//…请在此处输入您的项目选择代码。。。
}
多亏了我有了同样的问题,我终于找到了答案: 您需要像这样处理SelectionChanged事件和DropDownClosed: 在XAML中:
<ComboBox Name="cmbSelect" SelectionChanged="ComboBox_SelectionChanged" DropDownClosed="ComboBox_DropDownClosed">
<ComboBoxItem>1</ComboBoxItem>
<ComboBoxItem>2</ComboBoxItem>
<ComboBoxItem>3</ComboBoxItem>
</ComboBox>
这个问题困扰了我很长一段时间,因为所有的工作都不适合我:( 但好消息是,下面的方法对我的应用程序非常有效 基本思想是在
App.xmal.cs
中注册EventManager
以嗅探所有ComboBoxItem
的PreviewMouseLeftButtonDownEvent
,然后在选择项与所选项相同的情况下触发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
:)这是用于附加到组合框的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" />
对于我
组合框。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;
}
}
使用
SelectionChangeCommitted(对象发送方,事件参数)
event
对于UWP(Windows应用商店)应用程序,上述各项均无效(PointerPressed不启动;不存在预览、DropDownClosed或SelectedIndexChanged事件)
我不得不求助于覆盖组合框的透明按钮(但不是它的下拉箭头)。按箭头时,列表会像往常一样下拉,组合框的SelectionChanged事件会触发。单击组合框上的任何其他位置时,将触发透明按钮的单击事件,允许您重新选择组合框的当前值
一些工作XAML代码:
<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>
一些工作C#代码:
//
///不可能简单地单击组合框来再次选择显示的值。它总是下拉选项列表,但是
///如果从列表中选择的值与以前相同,则不会引发SelectionChanged事件
///
///为了处理这个问题,一个透明按钮覆盖在组合框上(但不是它的下拉箭头),以允许重新选择旧值
///因此,点击下拉箭头允许用户从列表中选择一个新选项,但是
///单击组合框中的任何其他位置可重新选择上一个值
///
private void ClickedComboButValueHasntChanged(对象发送者,路由目标)
{
//您还可以虚拟SelectionChangedEvent事件,并引发它以调用下面的函数\u SelectionChanged handler
输入函数(NewFunctionSelect.SelectedValue作为字符串);
}
私有无效函数\u SelectionChanged(对象发送方,SelectionChangedEventArgs e)
{
输入的函数(例如,作为字符串的AddedItems[0];
}
我希望下面的技巧能对您有所帮助
您可以绑定这两个事件
combobox.SelectionChanged += OnSelectionChanged;
combobox.DropDownOpened += OnDropDownOpened;
并强制所选项目在OnDropDownOpen中为空
private 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
}
}
每个ComboBoxItem实例都有PreviewMouseDown事件。如果您将在每个ComboBoxItem上订阅此事件的自定义处理程序,您将有机会处理下拉列表上的每次单击
// Subscribe on ComboBoxItem-s events.
comboBox.Items.Cast<ComboBoxItem>().ToList().ForEach(i => i.PreviewMouseDown += ComboBoxItem_PreviewMouseDown);
private void ComboBoxItem_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
// your handler logic...
}
//订阅ComboBoxItem-s事件。
comboBox.Items.Cast().ToList().ForEach(i=>i.PreviewMouseDown+=ComboBoxItem\u PreviewMouseDown);
私人无效组合
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (combobox.SelectedItem != null)
{
//Do something with the selected item
}
}
// Subscribe on ComboBoxItem-s events.
comboBox.Items.Cast<ComboBoxItem>().ToList().ForEach(i => i.PreviewMouseDown += ComboBoxItem_PreviewMouseDown);
private void ComboBoxItem_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
// your handler logic...
}
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;
}
}
private void ComboBox_Symbols_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count == 0)
return;
//Some Other Codes
}
private void OnDropDownClosed(object sender, EventArgs e)
{
if (combobox.SelectedItem == null) return;
// Do actions
}