none
ayuda con drawitem de un combobox multiculumn en VB.NET RRS feed

  • Pregunta

  • buenos dias a todos gracias por su ayuda.

    tengo el siguiente problema, encontre un codigo que hace que pueda tener un combobox con dos columnas y todo perfecto hasta que me doy cuenta que el dropdown no se ajusta al tamaño que yo quiero por ejemplo mi  combobox tiene un ancho de 50 y el dropdown se divide a la mitad y lo que yo quiero es que la columna 1 se quede igual pero que la columna dos sea 3 veces mas ancho. los datos los saco de una base de datos y el combobox esta enlazado a un datatable

    en esta primera parte solo muestro como lleno el datatable

        Private Sub Form1_Load(sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
            Dim query As String = "SELECT campo1, campo2 FROM tabla1;"
            Dim cmd As New MySqlCommand
            Dim da As New MySqlDataAdapter
            Dim dtTest As New DataTable
            Dim con As MySqlConnection = New MySqlConnection(server)
            Try
                con.Open()
                With cmd
                    .Connection = con
                    .CommandText = query
                End With
                da.SelectCommand = cmd
                da.Fill(dtTest)
                ComboBox1.DataSource = dtTest
                ComboBox1.DisplayMember = "campo1"
                ComboBox1.ValueMember = "campo2"
    
                ComboBox1.DrawMode = DrawMode.OwnerDrawFixed
            
             Catch ex As Exception
                MsgBox("Error " & vbCrLf & ex.Message, MsgBoxStyle.Critical)
            End Try
            con.Close()
            con.Dispose()
        End Sub
     

    Private Sub ComboBox1_DrawItem(ByVal sender As System.Object, _ ByVal e As System.Windows.Forms.DrawItemEventArgs) _ Handles ComboBox1.DrawItem ' Draw the default background e.DrawBackground() ' The ComboBox is bound to a DataTable, ' so the items are DataRowView objects. Dim drv As DataRowView = CType(ComboBox1.Items(e.Index), DataRowView) ' Retrieve the value of each column. Dim id As Integer = drv("campo1").ToString() Dim name As String = drv("campo2").ToString() ' Get the bounds for the first column Dim r1 As Rectangle = e.Bounds r1.Width = r1.Width / 2 ' Draw the text on the first column Using sb As SolidBrush = New SolidBrush(e.ForeColor) e.Graphics.DrawString(id, e.Font, sb, r1) End Using ' Draw a line to isolate the columns Using p As Pen = New Pen(Color.Black) e.Graphics.DrawLine(p, r1.Right, 0, r1.Right, r1.Bottom) End Using ' Get the bounds for the second column Dim r2 As Rectangle = e.Bounds r2.X = e.Bounds.Width / 2 r2.Width = r2.Width / 2 ' Draw the text on the second column Using sb As SolidBrush = New SolidBrush(e.ForeColor) e.Graphics.DrawString(name, e.Font, sb, r2) End Using End Sub

    en esta ultima parte es donde se dibujan las 2 columnas y en la parte de la segunda columna es la que quiero dibujar mas ancha

    intente con r2.Width = r2.Width * 2 pero no me salio nose que hacer

    jueves, 18 de febrero de 2016 17:07

Respuestas

  • comboBox1.DropDownWidth = 350

    Public Partial Class MainForm
    	Public Sub New()
    		Me.InitializeComponent()
    	End Sub
    	
    	Sub MainFormLoad(sender As Object, e As EventArgs)
    		comboBox1.Items.Add(New Dato("aaaa", "bbbbb", "ccccc"))
    		comboBox1.Items.Add(New Dato("ddd", "e", "ffffffffff"))
    		comboBox1.Items.Add(New Dato("ggggggg", "hhhhhhhhh", "i"))
    		comboBox1.DropDownWidth = 350
    	End Sub
    	
    	Sub ComboBox1DrawItem(sender As Object, e As DrawItemEventArgs)
    		e.DrawBackground()
    		Dim drv As Dato = CType(ComboBox1.Items(e.Index), Dato)
    		
    		Dim sf As New StringFormat
    		sf.SetTabStops(0, New Single(){80, 150})
    		e.Graphics.DrawString(drv.ToString, e.Font, Brushes.BurlyWood, e.Bounds, sf)
    		
    		Dim p As Pen = New Pen(Color.Black)
    		
    		e.Graphics.DrawLine(p, 78, 0, 78, e.Bounds.Bottom)
    		e.Graphics.DrawLine(p, 228, 0, 228, e.Bounds.Bottom)
    		
    	End Sub
    End Class
    
    Class dato
    	Public uno As String	
    	Public dos As String	
    	Public tres As String	
    	
    	Sub New(a As String, b As String, c As String)
    		uno=a
    		dos=b
    		tres=c
    	End Sub
    	
    	Public Overrides Function ToString() As String
    		Return String.Format("{1}{0}{2}{0}{3}", ControlChars.Tab, uno, dos, tres)
    	End Function
    
    End Class
    El uso de using me parece puro snobismo. Me gustaría escuchar su justificación. Pen es un tipo del clr y el gc se hará cargo de él, luego que la variable se hunda en el stack y pierda su scope. A nosotros nos tiene sin cuidado cuando el sistema libera el HPEN, y no tenemos necesidad alguna de forzar el dispose.


    • Editado Walter MD sábado, 20 de febrero de 2016 19:38
    • Marcado como respuesta RHCRD lunes, 22 de febrero de 2016 15:06
    sábado, 20 de febrero de 2016 18:09

Todas las respuestas

  • podrias explicarte mejor? no te entendi disculpa
    viernes, 19 de febrero de 2016 1:10
  • cambie OwnerDrawFixed por OwnerDrawVariable y por None yno funcionó no se a que te referias
    viernes, 19 de febrero de 2016 1:17
  • alguna idea?
    viernes, 19 de febrero de 2016 19:18
  • Deberías modificar el cálculo del ancho de las columnas:

            ' Get the bounds for the first column
            Dim r1 As Rectangle = e.Bounds
            r1.Width = r1.Width / 4
    
            ' Draw the text on the first column
            Using sb As SolidBrush = New SolidBrush(e.ForeColor)
                e.Graphics.DrawString(id, e.Font, sb, r1)
            End Using
    
            ' Draw a line to isolate the columns 
            Using p As Pen = New Pen(Color.Black)
                e.Graphics.DrawLine(p, r1.Right, 0, r1.Right, r1.Bottom)
            End Using
    
            ' Get the bounds for the second column
            Dim r2 As Rectangle = e.Bounds
            r2.X = e.Bounds.Width / 4
            r2.Width = r2.Width * 3 / 4


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...

    viernes, 19 de febrero de 2016 20:55
  • no no es lo qu queria hacer, ahi solo se hizo mas chico una columna para darle mas espacio a la otra yo solo quiero que la segunda columna sea mas grande
    viernes, 19 de febrero de 2016 22:16
  • comboBox1.DropDownWidth = 350

    Public Partial Class MainForm
    	Public Sub New()
    		Me.InitializeComponent()
    	End Sub
    	
    	Sub MainFormLoad(sender As Object, e As EventArgs)
    		comboBox1.Items.Add(New Dato("aaaa", "bbbbb", "ccccc"))
    		comboBox1.Items.Add(New Dato("ddd", "e", "ffffffffff"))
    		comboBox1.Items.Add(New Dato("ggggggg", "hhhhhhhhh", "i"))
    		comboBox1.DropDownWidth = 350
    	End Sub
    	
    	Sub ComboBox1DrawItem(sender As Object, e As DrawItemEventArgs)
    		e.DrawBackground()
    		Dim drv As Dato = CType(ComboBox1.Items(e.Index), Dato)
    		
    		Dim sf As New StringFormat
    		sf.SetTabStops(0, New Single(){80, 150})
    		e.Graphics.DrawString(drv.ToString, e.Font, Brushes.BurlyWood, e.Bounds, sf)
    		
    		Dim p As Pen = New Pen(Color.Black)
    		
    		e.Graphics.DrawLine(p, 78, 0, 78, e.Bounds.Bottom)
    		e.Graphics.DrawLine(p, 228, 0, 228, e.Bounds.Bottom)
    		
    	End Sub
    End Class
    
    Class dato
    	Public uno As String	
    	Public dos As String	
    	Public tres As String	
    	
    	Sub New(a As String, b As String, c As String)
    		uno=a
    		dos=b
    		tres=c
    	End Sub
    	
    	Public Overrides Function ToString() As String
    		Return String.Format("{1}{0}{2}{0}{3}", ControlChars.Tab, uno, dos, tres)
    	End Function
    
    End Class
    El uso de using me parece puro snobismo. Me gustaría escuchar su justificación. Pen es un tipo del clr y el gc se hará cargo de él, luego que la variable se hunda en el stack y pierda su scope. A nosotros nos tiene sin cuidado cuando el sistema libera el HPEN, y no tenemos necesidad alguna de forzar el dispose.


    • Editado Walter MD sábado, 20 de febrero de 2016 19:38
    • Marcado como respuesta RHCRD lunes, 22 de febrero de 2016 15:06
    sábado, 20 de febrero de 2016 18:09
  • no no es lo qu queria hacer, ahi solo se hizo mas chico una columna para darle mas espacio a la otra yo solo quiero que la segunda columna sea mas grande

    Pero el código que te pongo lo que hace es emplear un cuarto del ancho del combobox para la primera columna y tres cuartos para la segunda. Si quieres que las columnas sean más anchas no tienes más que hacer el combobox más ancho.


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...

    sábado, 20 de febrero de 2016 22:38
  • no podia hacer mas ancho el combobox pero gracias detodos modos, Walter MD me dio la respuesta
    lunes, 22 de febrero de 2016 15:06