visual net item ejemplos c# .net winforms winapi listbox

c# - net - listbox visual basic ejemplos



¿Cómo puedo configurar diferentes textos de Información sobre herramientas para cada elemento en un cuadro de lista? (7)

Tengo un listbox que está vinculado a una Colección de objetos. El cuadro de lista está configurado para mostrar una propiedad de identificación de cada objeto. Me gustaría mostrar una información sobre herramientas con información específica del elemento dentro del cuadro de lista que se está pasando por alto en lugar de una información sobre herramientas para el cuadro de lista como un todo.

Estoy trabajando dentro de WinForms y gracias a algunas útiles publicaciones de blog reuní una solución bastante buena, que quería compartir.

Me interesaría ver si hay otras soluciones elegantes para este problema, o cómo se puede hacer esto en WPF.


Al usar onmouseover , puede recorrer cada elemento de la lista y mostrar la ToolTip

onmouseover="doTooltipProd(event,''''); function doTooltipProd(e,tipObj) { Tooltip.init(); if ( typeof Tooltip == "undefined" || !Tooltip.ready ) { return; } mCounter = 1; for (m=1;m<=document.getElementById(''lobProductId'').length;m++) { var mCurrent = document.getElementById(''lobProductId'').options[m]; if(mCurrent != null && mCurrent != "null") { if (mCurrent.selected) { mText = mCurrent.text; Tooltip.show(e, mText); } } } }


Aquí hay un Estilo que crea un grupo de RadioButtons usando un ListBox. Todo está dirigido a MVVM-ing. MyClass contiene dos propiedades de cadena: MyName y MyToolTip. Esto mostrará la lista de RadioButtons, incluida la información sobre herramientas adecuada. De interés para este hilo es Setter para ToolTip near bottom haciendo de esto una solución Xaml.

Ejemplo de uso:

ListBox Style = "{StaticResource radioListBox}" ItemsSource = "{Binding MyClass}" SelectedValue = "{Binding SelectedMyClass}" />

Estilo:

<Style x:Key="radioListBox" TargetType="ListBox" BasedOn="{StaticResource {x:Type ListBox}}"> <Setter Property="BorderThickness" Value="0" /> <Setter Property="Margin" Value="5" /> <Setter Property="Background" Value="{x:Null}" /> <Setter Property="ItemContainerStyle"> <Setter.Value> <Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListBoxItem"> <Grid Background="Transparent"> <RadioButton Focusable="False" IsHitTestVisible="False" IsChecked="{TemplateBinding IsSelected}" Content="{Binding MyName}"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> <Setter Property="ToolTip" Value="{Binding MyToolTip}" /> </Style> </Setter.Value> </Setter> </Style>


Con el evento MouseMove, puede realizar un seguimiento del índice del elemento sobre el que está el mouse y almacenarlo en una variable que mantiene su valor entre MouseMoves. Cada vez que se activa MouseMove, comprueba si el índice ha cambiado. Si es así, deshabilita la información sobre herramientas, cambia el texto de información sobre herramientas para este control y luego lo vuelve a activar.

A continuación se muestra un ejemplo en el que se muestra una propiedad única de una clase de automóvil en un ListBox, pero luego se muestra información completa al pasar el mouse sobre una fila. Para que este ejemplo funcione, todo lo que necesita es un ListBox llamado lstCars con un evento MouseMove y un componente de texto de información sobre herramientas llamado tt1 en su WinForm.

Definición de la clase de auto:

class Car { // Main properties: public string Model { get; set; } public string Make { get; set; } public int InsuranceGroup { get; set; } public string OwnerName { get; set; } // Read only property combining all the other informaiton: public string Info { get { return string.Format("{0} {1}/nOwner: {2}/nInsurance group: {3}", Make, Model, OwnerName, InsuranceGroup); } } }

Evento de carga de formulario:

private void Form1_Load(object sender, System.EventArgs e) { // Set up a list of cars: List<Car> allCars = new List<Car>(); allCars.Add(new Car { Make = "Toyota", Model = "Yaris", InsuranceGroup = 6, OwnerName = "Joe Bloggs" }); allCars.Add(new Car { Make = "Mercedes", Model = "AMG", InsuranceGroup = 50, OwnerName = "Mr Rich" }); allCars.Add(new Car { Make = "Ford", Model = "Escort", InsuranceGroup = 10, OwnerName = "Fred Normal" }); // Attach the list of cars to the ListBox: lstCars.DataSource = allCars; lstCars.DisplayMember = "Model"; }

El código de información sobre herramientas (incluida la creación de la variable de nivel de clase llamada hoveredIndex):

// Class variable to keep track of which row is currently selected: int hoveredIndex = -1; private void lstCars_MouseMove(object sender, MouseEventArgs e) { // See which row is currently under the mouse: int newHoveredIndex = lstCars.IndexFromPoint(e.Location); // If the row has changed since last moving the mouse: if (hoveredIndex != newHoveredIndex) { // Change the variable for the next time we move the mouse: hoveredIndex = newHoveredIndex; // If over a row showing data (rather than blank space): if (hoveredIndex > -1) { //Set tooltip text for the row now under the mouse: tt1.Active = false; tt1.SetToolTip(lstCars, ((Car)lstCars.Items[hoveredIndex]).Info); tt1.Active = true; } } }


Creo que la mejor opción, ya que su databinding your listbox a objetos, sería usar un datatemplate. Entonces podrías hacer algo como esto:

<ListBox Width="400" Margin="10" ItemsSource="{Binding Source={StaticResource myTodoList}}"> <ListBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Path=TaskName}" ToolTipService.ToolTip="{Binding Path=TaskName}"/> </DataTemplate> </ListBox.ItemTemplate> </ListBox>

Por supuesto, reemplazará el enlace de ItemsSource por el que sea su fuente de enlace, y las partes vinculantes de Path con cualquier propiedad pública de los objetos de la lista que realmente quiera mostrar. Más detalles disponibles en msdn


Hay dos subproblemas principales que uno debe resolver para resolver este problema:

  1. Determine qué elemento está siendo sobrevolado
  2. Haga que el evento MouseHover se dispare cuando el usuario haya pasado el cursor sobre un elemento, luego mueva el cursor dentro del cuadro de lista y pase el cursor sobre otro elemento.

El primer problema es bastante simple de resolver. Al invocar un método como el siguiente en su controlador para MouseHover, puede determinar qué elemento está sobrevolando:

private ITypeOfObjectsBoundToListBox DetermineHoveredItem() { Point screenPosition = ListBox.MousePosition; Point listBoxClientAreaPosition = listBox.PointToClient(screenPosition); int hoveredIndex = listBox.IndexFromPoint(listBoxClientAreaPosition); if (hoveredIndex != -1) return listBox.Items[hoveredIndex] as ITypeOfObjectsBoundToListBox; else return null; }

Luego use el valor devuelto para configurar la información sobre herramientas según sea necesario.

El segundo problema es que normalmente el evento MouseHover no se dispara nuevamente hasta que el cursor ha salido del área de control del cliente y luego regresa.

Puede evitar esto al envolver la llamada TrackMouseEvent Win32API. En el siguiente código, el método ResetMouseHover ajusta la llamada API para obtener el efecto deseado: restablecer el temporizador subyacente que controla cuando se activa el evento de desplazamiento.

public static class MouseInput { // TME_HOVER // The caller wants hover notification. Notification is delivered as a // WM_MOUSEHOVER message. If the caller requests hover tracking while // hover tracking is already active, the hover timer will be reset. private const int TME_HOVER = 0x1; private struct TRACKMOUSEEVENT { // Size of the structure - calculated in the constructor public int cbSize; // value that we''ll set to specify we want to start over Mouse Hover and get // notification when the hover has happened public int dwFlags; // Handle to what''s interested in the event public IntPtr hwndTrack; // How long it takes for a hover to occur public int dwHoverTime; // Setting things up specifically for a simple reset public TRACKMOUSEEVENT(IntPtr hWnd) { this.cbSize = Marshal.SizeOf(typeof(TRACKMOUSEEVENT)); this.hwndTrack = hWnd; this.dwHoverTime = SystemInformation.MouseHoverTime; this.dwFlags = TME_HOVER; } } // Declaration of the Win32API function [DllImport("user32")] private static extern bool TrackMouseEvent(ref TRACKMOUSEEVENT lpEventTrack); public static void ResetMouseHover(IntPtr windowTrackingMouseHandle) { // Set up the parameter collection for the API call so that the appropriate // control fires the event TRACKMOUSEEVENT parameterBag = new TRACKMOUSEEVENT(windowTrackingMouseHandle); // The actual API call TrackMouseEvent(ref parameterBag); }

}

Con la envoltura en su lugar, simplemente puede llamar a ResetMouseHover (listBox.Handle) al final de su controlador MouseHover y el evento de desplazamiento se disparará nuevamente incluso cuando el cursor se mantenga dentro de los límites del control.

Estoy seguro de que este enfoque, pegando todo el código en el manejador MouseHover debe dar como resultado más eventos de MouseHover que son realmente necesarios, pero hará el trabajo. Cualquier mejora es más que bienvenida.


Puede usar este código simple que usa el evento onMouseMove de ListBox en WinForms:

private void ListBoxOnMouseMove(object sender, MouseEventArgs mouseEventArgs) { var listbox = sender as ListBox; if (listbox == null) return; // set tool tip for listbox var strTip = string.Empty; var index = listbox.IndexFromPoint(mouseEventArgs.Location); if ((index >= 0) && (index < listbox.Items.Count)) strTip = listbox.Items[index].ToString(); if (_toolTip.GetToolTip(listbox) != strTip) { _toolTip.SetToolTip(listbox, strTip); } }

Por supuesto, tendrá que iniciar el objeto ToolTip en el constructor o alguna función init:

_toolTip = new ToolTip { AutoPopDelay = 5000, InitialDelay = 1000, ReshowDelay = 500, ShowAlways = true };

¡Disfrutar!


Usando el atributo de título, podemos establecer la información sobre herramientas para cada elemento de la lista en un cuadro de lista.

Bucle esto para todos los elementos en un cuadro de lista.

ListItem li = new ListItem("text","key"); li.Attributes.Add("title","tool tip text");

Espero que esto ayude.