selectionchangecommitted seleccionar seleccionado saber obtener item evento esta ejemplos como change c# wpf

seleccionar - obtener el item seleccionado de un combobox c#



El controlador de eventos que se usarĂ¡ para el elemento seleccionado de ComboBox(el elemento seleccionado no necesariamente cambia) (10)

Objetivo: emitir un evento cuando se seleccionan los elementos en una lista desplegable de cuadro combinado.

Problema: utilizando "SelectionChanged", sin embargo, si el usuario elige el mismo elemento que el elemento que se está seleccionando actualmente, entonces la selección no se modifica y, por lo tanto, este evento no se activará.

Pregunta: ¿Qué otro controlador de eventos (u otras formas) que puedo usar para emitir un evento, independientemente del elemento seleccionado, se modifica o no siempre que el mouse haga clic en ese elemento y ese elemento se esté seleccionando?

(Aclaración: el problema es cómo activar "algo" cuando se selecciona de nuevo el mismo elemento. No hay duplicados en la lista desplegable. Escenario: seleccione por primera vez el elemento 1, cierre el menú desplegable. Y nuevamente, abra el cuadro desplegable y seleccione artículo 1 cuando se activan algunas funciones.)

Solución : por ahora no parece haber una solución directa para hacer esto. Pero de acuerdo con cada proyecto individual, puede haber formas de solucionarlo. (Por favor, actualice si hay buenas maneras de hacer esto). Gracias.


Cada instancia de ComboBoxItem tiene el evento PreviewMouseDown. Si suscribe su controlador personalizado en este evento en cada ComboBoxItem, tendrá la oportunidad de manejar cada clic en la lista desplegable.

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


Espero que encuentres útil el siguiente truco.

Puedes vincular ambos eventos

combobox.SelectionChanged += OnSelectionChanged; combobox.DropDownOpened += OnDropDownOpened;

Y forzar el elemento seleccionado a nulo dentro de OnDropDownOpened

private void OnDropDownOpened(object sender, EventArgs e) { combobox.SelectedItem = null; }

Y haga lo que necesite con el elemento dentro de OnSelectionChanged. El OnSelectionChanged se levantará cada vez que abra el cuadro combinado, pero puede verificar si SelectedItem es nulo dentro del método y omita el comando

private void OnSelectionChanged(object sender, SelectionChangedEventArgs e) { if (combobox.SelectedItem != null) { //Do something with the selected item } }


Este es un DependencyObject para adjuntar a un ComboBox.

Registra el elemento seleccionado actualmente cuando se abre el menú desplegable y, a continuación, activa el evento SelectionChanged si el mismo índice aún está seleccionado cuando se cierra el menú desplegable. Es posible que deba modificarse para que funcione con la selección del teclado.

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

y agrega tu prefijo de espacio de nombres para que sea accesible.

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

y luego hay que adjuntarlo como tal

<ComboBox ut:ComboAlwaysFireSelection.Active="True" />


Este problema me molesta durante mucho tiempo, ya que ninguno de los arreglos me funcionó :(

Pero la buena noticia es que el siguiente método funciona bien para mi aplicación.

La idea básica es registrar un EventManager en App.xmal.cs para oler PreviewMouseLeftButtonDownEvent para todo ComboBoxItem , luego activar SelectionChangedEvent si el elemento de selección es el mismo que el elemento seleccionado, es decir, la selección se realiza sin cambiar el índice .

En 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())); } } }

Luego, para todos los cuadros combinados, registre SelectionChangedEvent de una manera normal:

<ComboBox ItemsSource="{Binding BindList}" SelectionChanged="YourSelectionChangedEventHandler"/>

Ahora, si dos índices son diferentes, nada especial excepto el proceso ordinario de manejo de eventos; si dos índices son iguales, primero se manejará el evento del ratón en el elemento y, por lo tanto, se activará el evento SelectionChangedEvent . De esta manera, ambas situaciones activarán SelectionChangedEvent :)


Para aplicaciones UWP (Tienda Windows), ninguna de las anteriores funcionará (PointerPressed no se activa; no hay eventos de Vista previa, DropDownClosed o SelectedIndexChanged)

Tuve que recurrir a un botón transparente que superpone el ComboBox (pero no su flecha desplegable). Cuando presiona sobre la flecha, la lista se despliega como de costumbre y el evento SelectionChanged del cuadro combinado se dispara. Cuando hace clic en cualquier otro lugar del cuadro combinado, se activa el evento de clic del botón transparente que le permite volver a seleccionar el valor actual del cuadro combinado.

Algunos código XAML de trabajo:

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

Algunos código de trabajo de C #:

/// <summary> /// It is impossible to simply click a ComboBox to select the shown value again. It always drops down the list of options but /// doesn''t raise SelectionChanged event if the value selected from the list is the same as before /// /// To handle this, a transparent button is overlaid over the ComboBox (but not its dropdown arrow) to allow reselecting the old value /// Thus clicking over the dropdown arrow allows the user to select a new option from the list, but /// clicking anywhere else in the Combo re-selects the previous value /// </summary> private void ClickedComboButValueHasntChanged(object sender, RoutedEventArgs e) { //You could also dummy up a SelectionChangedEvent event and raise it to invoke Function_SelectionChanged handler, below FunctionEntered(NewFunctionSelect.SelectedValue as string); } private void Function_SelectionChanged(object sender, SelectionChangedEventArgs e) { FunctionEntered(e.AddedItems[0] as string); }


Para mí ComboBox.DropDownClosed Evento lo hizo.

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


Puede probar " SelectedIndexChanged ", que activará el evento incluso si se selecciona el mismo elemento.


Puede utilizar el evento "ComboBoxItem.PreviewMouseDown". Entonces, cada vez que el mouse esté abajo en algún elemento, este evento se activará.

Para agregar este evento en XAML use "ComboBox.ItemContainerStyle" como en el siguiente ejemplo:

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

y manejarlo como de costumbre

void cmbItem_PreviewMouseDown(object sender, MouseButtonEventArgs e) { //...do your item selection code here... }

Gracias a MSDN


Tuve la misma pregunta y finalmente encontré la respuesta:

Debe manejar TANTO el evento SelectionChanged y el DropDownClosed de esta manera:

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


Utilice el evento SelectionChangeCommitted(object sender, EventArgs e) here