Avatar billede Lasse Novice
01. december 2005 - 18:23 Der er 11 kommentarer og
1 løsning

Hvordan er en combobox implementeret

Jeg har i sinde at lave en combobox. Det er ikke en mulighed at bruge den allerede eksisterende.

Ide 1) Lav en form, kald Show
Cons) Hoved formen mister fokus

De foelgende ideer bruger alle foelgende:

Vis form vha API ShowWindow(hWnd, 4).
I WndProc: if (m.Msg == (int)Msgs.WM_MOUSEACTIVATE) m.Result = (IntPtr)MouseActivateFlags.MA_NOACTIVATE;

Ide 2) Global hooks.
Cons) Virker ikke med 98

Ide 3) IMessageFilter og Application.AddMessageFilter
Cons) Virker ikke hvis man trykker paa hoved formens titel bar.

Jeg har soegt paa nettet, og jeg kan ikke finde nogen som der virkelig har lavet dette i C#. Er der nogen der kan hjaelpe mig med en ide her???
Avatar billede Syska Mester
01. december 2005 - 19:33 #1
Lytter lige med.... forstår ikke helt problemet, da du ikke har skrevet hvad du vil opnå, som den almindelige combobox ikke kan.....

// ouT
Avatar billede driis Nybegynder
01. december 2005 - 19:40 #2
Hmm jeg forstår heller ikke problemstillingen. Prøv at forklar lidt bedre, hvad du vil opnå ?
Avatar billede Lasse Novice
01. december 2005 - 19:46 #3
Der er 2 grunde til dette, hvoraf den foerste har primaer vaegt.

1) Jeg skal have lavet min egen grafik for comboboxen... i baade comboboxen og i drop down list boxen. Det vil jeg formode er umuligt (laes meget besvaerligt), hvis jeg skal overskrive. Jeg troede ikke det var svaert at lave en selv, men det er det maaske...

2) Jeg har i nogle maaneder funderet over HVORDAN comboboxen er implementeret. Hvordan er det muligt at vise et vindue uden fokus, og lukke det idet der bliver trykket hvor som helst paa skaermen.
Avatar billede driis Nybegynder
01. december 2005 - 20:17 #4
1) Hvis du arver fra ComboBox, er det ret nemt at lave din egen grafik.
Jeg tror nok jeg har et eksempel ...
Avatar billede driis Nybegynder
01. december 2005 - 20:22 #5
Jeg kunne ikke lige finde et eksempel. Jeg vil godt lave et, hvis du er interesseret.

Men hvis du arver fra ComboBox og sætter OwnerDraw = true, kan du selv tage dig af at lave den grafik, der skal til.

Ad 2), hvis du er nysgerrig efter hvordan den er implementeret, vil jeg anbefale dig at tage et kig på den i Lutz Roeder's Reflector.
http://www.aisto.com/roeder/dotnet/
Avatar billede Lasse Novice
01. december 2005 - 22:37 #6
Ville man kunne lave dette ved at overskrive:

1) Comboboxen skal have en border der er 5 bred, og knappens look skal aendres.

2) Listboxen der fremkommer skal ogsaa have en border der er 5 bred.

Jeg har kigget lidt paa roeaders program og det virker som jeg kan finde ud af hvordan det er implementeret ved brug af det. Takker. Svar => point

Konklusion:
Mange gange vil det vaere nemmere at lave en kontrol selv, istedet for at overskrive standard kontrollerne (isaer hvis man skal ned og rode ved messages).
Avatar billede zaknafein Praktikant
01. december 2005 - 23:05 #7
Du kan oprette en normal textbox, og en knap til højre for den.
På knappen kan du sætte et billede ind. Så har du din egen grafik på den.
Din liste kan bare være listbox, hvis den ikke skal laves så meget om.
Eller kan du lave din egen klasse og arve fra et eksisterende element.

Mht det med focus, kan du nemt køre en hide() på din liste, når der trykkes et sted.
Når man så trykker på din custom knap, vises din liste.

Så skal du bare lave funktionaliteten med at markere det element i listen, som matcher det man skriver i tekstboksen.
Til det er der en "FindString" metode på en listeBox.

int selected = listBox1.FindString(source);
listBox1.SelectedIndex = selected;

Så markeres det element der matcher.
Avatar billede Lasse Novice
02. december 2005 - 15:56 #8
zaknafein>> Se Ide 1 og dens cons... Virker ikke som en rigtig combobox.
Avatar billede driis Nybegynder
03. december 2005 - 19:30 #9
Jeg er uenig med dig i at det er bedre at lave en kontrol selv; hvis du arver fra en af standardkontrollerne får du det meste af funktionaliteten foræret, og din nye kontrols look-and-feel er konsistent med standardkontrollerne.

Jeg har kigget lidt på dit problem, og er kommet frem til følgende:
1) ComboBox er implementeret med 2 child windows, Edit delen og drop-down delen
2) Tegning af ComboBox sker i DrawFlatCombo, som desværre er en privat metode, hvorfor vi ikke kan override den
3) Vi kan bruge Paint eventet til at tegne vores egen version af ComboBox'en
4) Jeg fandt dog, at Paint eventet på en ComboBox ikke bliver fyret af, dokumentationen siger også at den er til "internal use". Derfor er det nødvendigt at kigge på vinduets messages og selv få Paint eventet til at fyre rigtigt.
5) Du kan selv tegne de enkelte items, ved at sætte DrawMode til en af OwnerDraw varianterne.
Avatar billede driis Nybegynder
03. december 2005 - 19:35 #10
Her er et eksempel til .NET 2.0, det skal måske tilpasses lidt hvis du skal bruge det i ver 1.1.

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace ComboTest
{
    /// <summary>
    /// An extended combobox with a working paint event
    /// </summary>
    class ComboBoxEx : ComboBox
    {
        /// <summary>
        /// Constructor
        /// </summary>
        public ComboBoxEx()
        {
            this.DrawMode = DrawMode.OwnerDrawFixed;
            this.DrawItem += new DrawItemEventHandler(ComboBoxEx_DrawItem);
            this.Paint += new PaintEventHandler(ComboBoxEx_Paint);
        }

        /// <summary>
        /// Handles the paint event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ComboBoxEx_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            Rectangle rect = ClientRectangle;
            rect.X = rect.Right - 25;
            g.FillRectangle(Brushes.Navy, rect);
        }

        /// <summary>
        /// Draw one item in the drop-down
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ComboBoxEx_DrawItem(object sender, DrawItemEventArgs e)
        {
            Graphics g = e.Graphics;
            e.DrawBackground();
            float w = 2;
           
            if (e.State == DrawItemState.Selected)
                w += 3;
           
            Pen p = new Pen(e.ForeColor,w);
            g.DrawRectangle(p, e.Bounds);
            PointF pos = new PointF(e.Bounds.X + w + 1, e.Bounds.Y + w);
            g.DrawString(Items[e.Index].ToString(), e.Font, new SolidBrush(e.ForeColor), pos);

        }

        /// <summary>
        /// Overrides WndProc to provide a functioning Paint event in ComboBox
        /// </summary>
        /// <param name="m"></param>
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            if (m.Msg == WM_PAINT)
            {
                // fake a Paint event
                using (Graphics g = this.CreateGraphics())
                {                   
                    PaintEventArgs pea = new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle);
                    OnPaint(pea);
                }
            }
        }

        /// <summary>
        /// Message WM_PAINT
        /// </summary>
        private const int WM_PAINT = 15;
    }
}
Avatar billede Lasse Novice
06. december 2005 - 00:33 #11
driss>> Det er rigtig meget der skal overskrives. Hvad med hvorhenne man trykker paa comboboxen (pga. tykkere border) etc. I sidste ende vil det vaere federe at skrive en selv, om ikke andet for ogsaa at laere hvordan det er implementeret.

Jeg har kigget lidt paa reflector. Det viser sig at System.Windows.Forms. kun er et layer oven paa combobox kontrollen. Saa jeg er faktisk tilbage til hvor jeg startet - nemlig hvordan er en combobox implementeret???????????????
Avatar billede driis Nybegynder
06. december 2005 - 14:30 #12
Det er rigtigt, at stort set alle klasserne i System.Windows.Forms blot er (mere eller mindre avancerede) wrappers omkring de kontroller Win32 API stiller til rådighed. (F.eks. er ComboBox bygget op af 2 native window's som igen er en wrapper omkring et HWND).

Du kan ikke få lov at dykke dybere ned i hvordan det er implementeret - med mindre du overbeviser Microsoft om, at en Windows i open source er en god ting ;-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester