جعل القائمة المنسدلة Combobox تحتوي على عنصر التحكم ListView

إرسال مساهمة في موضوع

اذهب الى الأسفل

جعل القائمة المنسدلة Combobox تحتوي على عنصر التحكم ListView

مُساهمة من طرف المبرمج الطموح في الأحد نوفمبر 25, 2018 7:49 am

اهلا بكم

هذا مثال لجعل مربع التحرير والسرد [ندعوك للتسجيل في المنتدى أو التعريف بنفسك لمعاينة هذا الرابط]  يسمح بعرض عنصر تحكم [ندعوك للتسجيل في المنتدى أو التعريف بنفسك لمعاينة هذا الرابط] في شكل تقرير بحيث عند النقر فوق زر القائمة المنسدلة Combobox يقوم بعرض عنصر التحكم [ندعوك للتسجيل في المنتدى أو التعريف بنفسك لمعاينة هذا الرابط] ، وتحديد موضعه كأنه هو القائمة المنسدلة


يمكن أن يكون هذا المثال مفيدًا إذا كنت ترغب في الاطلاع على قائمة بالبيانات في شكل تقرير وبأعمدة متعددة ، وألا تشغل مساحة فى واجهة المشروع

كيف يتم ذلك

1_إضافة وحدة نمطية Class Module تسمى Class1 إلى المشروع

2_في النموذج قم بإضافة عنصري التحكم Listview و Combo.

1_إفتح  Class Module و إضافة التعليمات البرمجية التالية :

إنقر لمشاهدة الشفرة :

الكود:
Option Explicit



'الثوابت لاستخدامها مع SendMessage لضبط رؤوس الأعمدة

Private Const LVM_FIRST As Long = &H1000
Private Const LVM_SETCOLUMNWIDTH As Long = LVM_FIRST + 30

' وظيفة Api SendMessage للقيام AutoSize من Columnheaders
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
                ByVal hwnd As Long, _
                ByVal wMsg As Long, _
                ByVal wParam As Long, _
                lParam As Any) As Long

Private Declare Function GetWindowRect Lib "user32" ( _
    ByVal hwnd As Long, _
    lpRect As RECT) As Long
    

Private Declare Function GetWindowPlacement Lib "user32" ( _
    ByVal hwnd As Long, _
    lpwndpl As WINDOWPLACEMENT) As Long

Private Type POINTAPI
    x As Long
    y As Long
End Type

'لوضع ListView
Private Declare Function MoveWindow Lib "user32" ( _
    ByVal hwnd As Long, _
    ByVal x As Long, _
    ByVal y As Long, _
    ByVal nWidth As Long, _
    ByVal nHeight As Long, _
    ByVal bRepaint As Long) As Long

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
Private Type WINDOWPLACEMENT
        Length As Long
        flags As Long
        showCmd As Long
        ptMinPosition As POINTAPI
        ptMaxPosition As POINTAPI
        rcNormalPosition As RECT
End Type

' الترقيم لنوع تعديل العمود lv
Enum Ajustar_ColumnHeader
    NO_AJUSTAR = 0
    AJUSTAR_POR_ITEM = -1
    AJUSTAR_POR_COLUMNA = -2
End Enum

' متغيرات الكائنات الخاصة لـنافذة و الكمبو لاعتراض الأحداث
Private WithEvents m_Listview As ListView
Private WithEvents m_Formulario As Form
Private WithEvents m_Combobox As ComboBox

Private m_AutoSizeColumnHeaders As Ajustar_ColumnHeader
Public Height_Lista As Long
Public WidthLista As Long

' Sub que inicia ( recibe como argumeto el combo y el listview )
'*********************************************************************
Sub Init(El_ComboBox As ComboBox, El_ListView As ListView)
        
       ' verifica que el objeto no se haya instanciado
       If m_Combobox Is Nothing Then
            ' Instancia
            Set m_Combobox = El_ComboBox
            Set m_Listview = El_ListView
            ' para hacer referencia al form
            Set m_Formulario = El_ListView.Parent
       Else
            MsgBox "Ta se ejecut? el método Init ", vbInformation
            Exit Sub
       End If
      
       ' alto de la lista
       If Height_Lista = 0 Then
          Height_Lista = 250
       End If
      
       ' Propiedades del Listview
       With m_Listview
            .Visible = False
            .View = lvwReport
            .FullRowSelect = True
            .Appearance = ccFlat
            .TabStop = False
       End With
      
       ' Autosize de  los encabezados del lv
       Call Ajustar_Ancho_Columna(m_Listview, m_AutoSizeColumnHeaders)
      
       ' Selecciona el primer elemento para mostrarlo en el combo
       If m_Listview.ListItems.Count <> 0 Then
          m_Combobox.AddItem m_Listview.ListItems(1).Text
          m_Combobox.ListIndex = 0
       End If
End Sub


Private Sub Class_Initialize()
    m_AutoSizeColumnHeaders = AJUSTAR_POR_COLUMNA
End Sub

Private Sub m_Combobox_KeyPress(KeyAscii As Integer)
    Select Case KeyAscii
        Case 13: m_Combobox_DropDown
        'Case vbKeyEscape:
    End Select
End Sub

' cuando se hace clic en el formulario _
  se oculta la lista y se pasa el foco al combo
Private Sub m_Formulario_Click()
    If m_Listview.Visible Then
        m_Listview.Visible = False
        m_Combobox.SetFocus
    End If
End Sub

' evento al hacer clic en el item del lv
Private Sub m_ListView_itemclick(ByVal Item As MSComctlLib.ListItem)
    
    m_Combobox.Clear
    m_Combobox.AddItem Item.Text
    m_Combobox.ListIndex = 0

End Sub

Private Sub m_ComboBox_GostFocus()
    m_Listview.Visible = False
End Sub

Private Sub m_ComboBox_LostFocus()
    
    If Screen.ActiveControl.Name <> m_Listview.Name Then
       m_Listview.Visible = False
    End If
    
End Sub

Private Sub m_Listview_KeyPress(KeyAscii As Integer)
    Select Case KeyAscii
        ' despliega la lista al preeionar enter
        Case 13
            m_Listview.Visible = False
            m_Combobox.SetFocus
        ' oculta  el listview al presionar la tecla escape
        Case vbKeyEscape
            m_Listview.Visible = False
            m_Combobox.SetFocus
    End Select
End Sub

Private Sub m_Listview_LostFocus()
   m_Listview.Visible = False
   m_Combobox.SetFocus
End Sub


' al hacer clic en la lista desplegable
'''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub m_Combobox_DropDown()
    
    Static flag As Boolean
            
    flag = Not flag
    
    'este bloque solo se ejuta cuando se despliega, no cuando se oculta
    If flag Then
        
        Dim wp As WINDOWPLACEMENT
        
        Dim x As Long
        Dim y As Long
        Dim AnchoLista As Single
        Dim obj As Object
        
        Set obj = m_Combobox.Container
        
        ' esto es por si el lv est? en varios contenedores ( frames picture )
        While obj.hwnd <> 0 And obj.Name <> m_Formulario.Name
            GetWindowPlacement obj.hwnd, wp
            
            x = x + wp.rcNormalPosition.Left
            y = y + wp.rcNormalPosition.Top
            Set obj = obj.Container
        Wend
        
        GetWindowPlacement m_Combobox.hwnd, wp
        
        ' posici?n x e y del combo en pixels para luego posicionar el lv
        x = x + wp.rcNormalPosition.Left
        y = y + wp.rcNormalPosition.Top + (wp.rcNormalPosition.Bottom - _
                                           wp.rcNormalPosition.Top)
        
        ' ancho del combo en pixels
        If WidthLista = 0 Then
           AnchoLista = wp.rcNormalPosition.Right - wp.rcNormalPosition.Left
        Else
           AnchoLista = WidthLista
        End If
        
        ' posiciona el listview
        MoveWindow m_Listview.hwnd, x, y, _
                   AnchoLista, _
                   Height_Lista, 1
        
        ' le pone el foco, lo hace visible  y lo trae al frente
        m_Listview.Visible = True
        m_Listview.SetFocus
        m_Listview.ZOrder 0
        
        ' cuando no hay items, oculta los columnheaders ( opcional )
        If m_Listview.ListItems.Count = 0 And m_Listview.View = lvwReport Then
           m_Listview.HideColumnHeaders = True
        Else
           m_Listview.HideColumnHeaders = False
        End If
        
        flag = Not flag
    
    Else
        ' oculta el listview cuando se cierra
        m_Listview.Visible = False
    End If

End Sub

Private Sub m_Listview_MouseUp(Button As Integer, Shift As Integer, _
                                x As Single, y As Single)
    m_Combobox.SetFocus
    m_Listview.Visible = False

End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'Ajutar encabezados de columna
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Private Sub Ajustar_Ancho_Columna(El_ListView As ListView, _
                                 ByVal Modo_De_Ajuste As Ajustar_ColumnHeader)
  
   Dim La_Columna As Long
  
   If Modo_De_Ajuste = NO_AJUSTAR Then
      Exit Sub
   End If
  
   With El_ListView
      'Recorre los encabezados de columna
      For La_Columna = 1 To .ColumnHeaders.Count
         Call ListView_AutoSize(El_ListView, La_Columna, Modo_De_Ajuste)
      Next
  
   End With

End Sub
' Rutina que usa la sub Ajustar_Ancho_Columna
Private Sub ListView_AutoSize(El_ListView As ListView, _
                              ByVal La_Columna As Long, _
                              ByVal Modo_De_Ajuste As Long)

   With El_ListView
      
      'si no est? el ListView en modo reporte sale
      If .View = lvwReport Then
         'Si hay columnas
         If La_Columna >= 1 And La_Columna <= .ColumnHeaders.Count Then
            'Establece el Autosize
            Call SendMessage(.hwnd, LVM_SETCOLUMNWIDTH, _
                             La_Columna - 1, ByVal Modo_De_Ajuste)
         End If
      End If
   End With
End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

' Propiedades

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Property Get AutoSizeColumnHeaders() As Ajustar_ColumnHeader

  AutoSizeColumnHeaders = m_AutoSizeColumnHeaders

End Property

Property Let AutoSizeColumnHeaders(value As Ajustar_ColumnHeader)
    
  ' Asigna el valor a la propiedad
  m_AutoSizeColumnHeaders = value
  
  ' Verifica que el listview se haya referenciado
  If Not m_Listview Is Nothing Then
    Call Ajustar_Ancho_Columna(m_Listview, value)
  End If
End Property




4_ فى النافذة اضف التعليمات البرمجية التالية :

الكود:
Option Explicit

Dim ComboListview As Class1


Private Sub Form_Load()
    
    Dim Item As ListItem
    
    With ListView1
                
        ' تسمية رؤس الاعمدة
        .ColumnHeaders.Add , , "الاسم"
        .ColumnHeaders.Add , , "اللقب"
        .ColumnHeaders.Add , , "رقم العميل"
    
        ' إضافة بعض العناصر و SubItems إلى Listview
        
        Set Item = ListView1.ListItems.Add(, , "أحمد")
            Item.SubItems(1) = "المهدي"
            Item.SubItems(2) = "258"
        Set Item = ListView1.ListItems.Add(, , "ناهد")
            Item.SubItems(1) = "شريف"
            Item.SubItems(2) = "658"
        Set Item = ListView1.ListItems.Add(, , "اسماء")
            Item.SubItems(1) = "السيد"
            Item.SubItems(2) = "098"
        Set Item = ListView1.ListItems.Add(, , "عبد الرحمن")
            Item.SubItems(1) = "محمد"
            Item.SubItems(2) = "158"
        Set Item = ListView1.ListItems.Add(, , "حسي")
            Item.SubItems(1) = "السيد"
            Item.SubItems(2) = "168"
        Set Item = ListView1.ListItems.Add(, , "محمد")
            Item.SubItems(1) = "مختار"
            Item.SubItems(2) = "348"
        

        Dim i As Integer
        ' لتغير لون النص
        For i = 1 To ListView1.ListItems.Count
            ListView1.ListItems(i).ForeColor = vbBlue
        Next
    End With
    
    ' انشاء مثيل جديد من الفئة
    Set ComboListview = New Class1
    
    With ComboListview
             ' تحديد حجم الاعمدة
             .AutoSizeColumnHeaders = AJUSTAR_POR_COLUMNA
            
                    
        ' تمرير عنصري التحكم للدالة
        Call .Init(Combo1, ListView1)
    End With
    
End Sub

Private Sub Form_Unload(Cancel As Integer)
    ' تنظيف المتغيرات
    If Not ComboListview Is Nothing Then
        Set ComboListview = Nothing
    End If
End Sub

ملاحظات :

فى شفرة المثال اعلاه ستلاحظ أن هذه الوحدة Class1 لديها طريقة وثلاث خصائص وهم على النحو التالى :

الطريقة Init: هذه الطريقة هي الطريقة التي تبدأ فى تنفيذ الوحدة النمطية  ، ويجب أن يتم تمرير عنصري التحكم كمعلمة ، أي عنصر تحكم combobox المراد استخدامه وعناصر التحكم Listview ، على سبيل المثال

الكود:
Call .Init(Combo1, ListView1)

الخاصية AutoSizeColumnHeaders : و التى تستخدم لتحديد حجم العامود بالنسبة لتسمية رؤس الاعمدة تحتوي هذه الخاصية على ثلاث قيم وهي

  • ADJUST_BY_COLUMN :يتم ضبط العمود بواسطة التسمية التوضيحية للرأس
  • ADJUST_OF_ITEM : فسيضبط العمود نفسه وفقًا لأطول عنصر في العمود
  • NO_ADJUST :لا تفعل شيئا وتتركها كما هي ، أي بدون ضبط


الخصائص WidthList و HeightList لتعيين ارتفاع وعرض القائمة المنسدلة ، أي ListView. إذا لم يتم تحديد هذه القيم ، فسيتم استخدامها بشكل افتراضي كعرض ، وعرض combobox
avatar
المبرمج الطموح
الاشراف
الاشراف

تاريخ التسجيل : 18/02/2011
المساهمات : 178
النقاط : 332
التقيم : 14
الدولة : مصر
الجنس : ذكر

الرجوع الى أعلى الصفحة اذهب الى الأسفل

رد: جعل القائمة المنسدلة Combobox تحتوي على عنصر التحكم ListView

مُساهمة من طرف أحمد مناع في الأحد نوفمبر 25, 2018 6:32 pm

أحسنت يا [ندعوك للتسجيل في المنتدى أو التعريف بنفسك لمعاينة هذا الرابط]

ـــــــــــــــــــ التوقيع ــــــــــــــــــــ
سبحان الله وبحمدة .....سبحان الله العظيم
avatar
أحمد مناع
.
.

تاريخ التسجيل : 15/02/2011
المساهمات : 860
النقاط : 201563
التقيم : 83
الدولة : مصر
الجنس : ذكر

http://egy-tech.forumegypt.net

الرجوع الى أعلى الصفحة اذهب الى الأسفل

رد: جعل القائمة المنسدلة Combobox تحتوي على عنصر التحكم ListView

مُساهمة من طرف أبو الحسن عمران السليماني في السبت ديسمبر 08, 2018 7:43 pm

طرحٌ جميلٌ وأكثرُ  من  رائع
avatar
أبو الحسن عمران السليماني
.
.

تاريخ التسجيل : 14/09/2015
المساهمات : 4
النقاط : 7
التقيم : 1
الدولة : ليبيا
الجنس : ذكر

الرجوع الى أعلى الصفحة اذهب الى الأسفل

رد: جعل القائمة المنسدلة Combobox تحتوي على عنصر التحكم ListView

مُساهمة من طرف vbcoder اليوم في 9:10 am

شكرا جزيلا [ندعوك للتسجيل في المنتدى أو التعريف بنفسك لمعاينة هذا الرابط]
avatar
vbcoder
..
..

تاريخ التسجيل : 18/11/2018
المساهمات : 14
النقاط : 19
التقيم : 1
الدولة : مصر
الجنس : ذكر

الرجوع الى أعلى الصفحة اذهب الى الأسفل

الرجوع الى أعلى الصفحة

ََ

مواضيع ذات صلة


 
صلاحيات هذا المنتدى:
تستطيع الرد على المواضيع في هذا المنتدى