Geavanceerde Winforms programmeren in C #

In deze C # programmeerhandleiding zal ik me concentreren op de geavanceerde besturingselementen zoals ComboBoxes, Grids en ListViews en u laten zien hoe u ze waarschijnlijk zult gebruiken. Ik raak data en binding pas aan in een latere tutorial. Laten we beginnen met een eenvoudige bediening, een ComboBox.

De kern van een combo is een itemsverzameling en de eenvoudigste manier om dit te vullen is door een combo op het scherm te plaatsen, eigenschappen te selecteren (als u de eigenschappenvensters niet kunt zien, klikt u op Weergave in het bovenste menu en vervolgens op Eigenschappenvenster), zoekt u items en klikt u op de ellipsen knop. Je kunt dan de strings intypen, het programma compileren en de combo naar beneden trekken om keuzes te zien.

Stop nu het programma en voeg nog een paar cijfers toe: vier, vijf.. tot tien. Wanneer u het uitvoert, ziet u alleen 8 omdat dat de standaardwaarde is van MaxDropDownItems. Stel het gerust in op 20 of 3 en voer het vervolgens uit om te zien wat het doet.

instagram viewer

Het is vervelend dat wanneer het wordt geopend, comboBox1 staat en je het kunt bewerken. Dat is niet wat we willen. Zoek de eigenschap DropDownStyle en verander DropDown in DropDownList. (Het is een combinatie!). Nu is er geen tekst en kan deze niet worden bewerkt. U kunt een van de nummers selecteren, maar deze wordt altijd blanco geopend. Hoe selecteren we een nummer om mee te beginnen? Welnu, het is geen eigenschap die u tijdens het ontwerpen kunt instellen, maar het toevoegen van deze regel zal dat doen.

Voeg die regel toe in de constructor Form1 (). U moet de code voor het formulier bekijken (klik in de Solution Explorer met de rechtermuisknop op From1.cs en klik op Code bekijken. Vind InitializeComponent (); en voeg die regel onmiddellijk daarna toe.

Als u de eigenschap DropDownStyle voor de combo instelt op Eenvoudig en het programma uitvoert, krijgt u niets. Het zal niet selecteren of klikken of reageren. Waarom? Omdat je tijdens het ontwerpen de onderste rekgreep moet pakken en de hele bediening hoger moet maken.

In voorbeeld 2 heb ik de ComboBox hernoemd naar combo, de combo DropDownStyle terug veranderd naar DropDown zodat deze kan worden bewerkt en een knop Toevoegen toegevoegd genaamd btnAdd. Ik heb dubbel op de knop Toevoegen geklikt om een ​​event btnAdd_Click () event handler te maken en deze eventregel toegevoegd.

Wanneer u nu het programma uitvoert, typt u een nieuw nummer in, zegt u Elf en klikt u op toevoegen. De gebeurtenishandler neemt de tekst die u hebt ingevoerd (in combinatie). Tekst) en voegt het toe aan de itemsverzameling van de Combo. Klik op de Combo en we hebben nu een nieuw item Elf. Zo voeg je een nieuwe string toe aan een combo. Het verwijderen ervan is iets gecompliceerder omdat u de index van de snaar die u wilt verwijderen moet vinden en vervolgens moet verwijderen. De methode RemoveAt hieronder is een verzamelmethode om dit te doen. je hoeft alleen maar te specificeren welk item in de Removeindex parameter.

verwijdert de string op positie RemoveIndex. Als er n items in de combo zijn, zijn de geldige waarden 0 tot n-1. Voor 10 items, waarden 0..9.

Als dit de tekst niet vindt, wordt -1 geretourneerd, anders retourneert het de op 0 gebaseerde index van de tekenreeks in de combinatielijst. Er is ook een overbelaste methode van FindStringExact waarmee je kunt specificeren waar je de zoekopdracht begint, zodat je de eerste etc kunt overslaan als je duplicaten hebt. Dit kan handig zijn om duplicaten in een lijst te verwijderen.

Als u op btnAddMany_Click () klikt, wordt de tekst uit de combo gewist, wordt de inhoud van de combo-itemsverzameling gewist en wordt combo aangeroepen. AddRange (om de tekenreeksen uit de waardenmatrix toe te voegen. Hierna stelt het de SelectedIndex van de combo in op 0. Dit toont het eerste element in de combo. Als u items in een ComboBox toevoegt of verwijdert, kunt u het beste bijhouden welk item is geselecteerd. Als u SelectedIndex instelt op -1, worden de geselecteerde items verborgen.

De knop Lots toevoegen wist de lijst en voegt 10.000 nummers toe. Ik heb combo toegevoegd. BeginUpdate () en combo, EndUpdate () roept de lus rond om te voorkomen dat Windows flikkert en probeert het besturingselement bij te werken. Op mijn drie jaar oude pc duurt het iets meer dan een seconde om 100.000 nummers aan de combo toe te voegen.

Dit is een handige bediening voor het weergeven van tabelgegevens zonder de complexiteit van een raster. U kunt items weergeven als grote of kleine pictogrammen, als een lijst met pictogrammen in een verticale lijst of het handigst als een lijst met items en subitems in een raster en dat is wat we hier zullen doen.

Nadat u een ListView op een formulier heeft neergezet, klikt u op de eigenschap kolommen en voegt u 4 kolommen toe. Dit zijn TownName, X, Y en Pop. Stel de tekst in voor elke ColumnHeader. Als u de koppen in de ListView niet kunt zien (nadat u alle 4 hebt toegevoegd), stelt u de View Property van ListView in op Details. Als u de code voor dit voorbeeld bekijkt, bladert u naar beneden waar Windows Code Designer-code staat en vouwt u de regio uit, ziet u de code die de ListView maakt. Het is handig om te zien hoe het systeem werkt en u kunt deze code kopiëren en zelf gebruiken.

U kunt de breedte voor elke kolom handmatig instellen door de cursor over de koptekst te bewegen en deze te slepen. Of u kunt dit doen in de code die zichtbaar is nadat u de formulierontwerpregio hebt uitgebreid. Je zou code als volgt moeten zien:

Voor de populatiekolom worden wijzigingen in de code weerspiegeld in de ontwerper en vice versa. Merk op dat zelfs als u de eigenschap Vergrendeld instelt op waar, dit alleen van invloed is op de ontwerper en dat u tijdens runtime de grootte van kolommen kunt wijzigen.

ListViews hebben ook een aantal dynamische eigenschappen. Klik op de (Dynamische eigenschappen) en vink de gewenste eigenschap aan. Wanneer u een eigenschap instelt om dynamisch te zijn, wordt er een XML .config-bestand gemaakt en toegevoegd aan Solution Explorer.

Wijzigingen aanbrengen tijdens het ontwerpen is één ding, maar we moeten het echt doen als het programma actief is. Een ListView bestaat uit 0 of meer items. Elk item (een ListViewItem) heeft een teksteigenschap en een SubItems-verzameling. In de eerste kolom wordt de itemtekst weergegeven, in de volgende kolom wordt SubItem [0] .text weergegeven, vervolgens SubItem [1] .text enzovoort.

Ik heb een knop toegevoegd om een ​​rij en een bewerkingsvak voor de plaatsnaam toe te voegen. Voer een naam in het vak in en klik op Rij toevoegen. Dit voegt een nieuwe rij toe aan de ListView met de plaatsnaam in de eerste kolom en de volgende drie kolommen (SubItems [0..2]) worden gevuld met willekeurige getallen (geconverteerd naar tekenreeksen) door die tekenreeksen toe te voegen aan hen.

Stel nu de eigenschap ListView Multiselect in op false. We willen slechts één item tegelijk selecteren, maar als u er meer in één keer wilt verwijderen, is het vergelijkbaar, behalve dat u in omgekeerde volgorde moet doorlopen. (Als u in normale volgorde doorloopt en items verwijdert, zijn de volgende items niet gesynchroniseerd met de geselecteerde indexen).

Het rechtsklikmenu werkt nog niet omdat we er geen menu-items op kunnen weergeven. Dus klik met de rechtermuisknop op PopupMenu (onder het formulier) en je ziet Context Menu verschijnen bovenaan het formulier waar de normale Menu-editor verschijnt. Klik erop en typ Type hier, typ Item verwijderen. Het eigenschappenvenster zal een MenuItem tonen, dus hernoem dat naar mniRemove. Dubbelklik op dit menu-item en je zou menuItem1_Click event handler code functie moeten krijgen. Voeg deze code toe zodat het er zo uitziet.

Als u het item Verwijderen uit het oog verliest, klikt u gewoon op het PopupMenu-besturingselement op zichzelf onder het formulier in het formulier Designer. Dat brengt het weer in beeld.

Als u het echter uitvoert en geen item toevoegt en het selecteert, geeft u, wanneer u met de rechtermuisknop klikt en het menu ophaalt en op Item verwijderen klikt, een uitzondering omdat er geen geselecteerd item is. Dat is slecht programmeren, dus hier is hoe je het oplost. Dubbelklik op het pop-upevenement en voeg deze coderegel toe.

Een DataGridView is zowel het meest complexe als het nuttigste onderdeel dat gratis wordt geleverd bij C #. Het werkt met zowel gegevensbronnen (d.w.z. gegevens uit een database) als zonder (dwz gegevens die u programmatisch toevoegt). Voor de rest van deze tutorial zal ik laten zien dat het zonder gegevensbronnen wordt gebruikt. Voor eenvoudiger weergavebehoeften vindt u misschien een eenvoudige ListView meer geschikt.

Als u een oudere DataGrid-besturing hebt gebruikt, is dit slechts een van die op steroïden: het geeft u meer ingebouwde kolomtypen, kan werken met interne en externe gegevens, meer aanpassing van weergave (en gebeurtenissen) en geeft meer controle over celverwerking met bevriezende rijen en kolommen.

Wanneer u formulieren met rastergegevens ontwerpt, is het gebruikelijk om verschillende kolomtypen op te geven. Mogelijk hebt u selectievakjes in één kolom, alleen-lezen of bewerkbare tekst in een andere, en cursusnummers. Deze kolomtypen zijn meestal ook anders uitgelijnd met getallen die over het algemeen rechts zijn uitgelijnd, zodat de decimale punten op één lijn liggen. Op kolomniveau kun je kiezen uit Button, checkbox, ComboBox, Image, TextBox en Links. als dat niet genoeg is, kunt u uw eigen aangepaste typen aanpassen.

De eenvoudigste manier om kolommen toe te voegen is door te ontwerpen in de IDE. Zoals we eerder hebben gezien, schrijft dit gewoon code voor je en als je het een paar keer hebt gedaan, voeg je de code misschien liever zelf toe. Als je dit een paar keer hebt gedaan, krijg je inzicht in hoe je dit programmatisch kunt doen.

Laten we beginnen met het toevoegen van enkele kolommen, zet een DataGridView neer op het formulier en klik op de kleine pijl in de rechterbovenhoek. Klik vervolgens op Kolom toevoegen. Doe dit drie keer. Er verschijnt een dialoogvenster Kolom toevoegen waarin u de naam van de kolom instelt, de tekst die bovenaan de kolom moet worden weergegeven en u het type kunt kiezen. De eerste kolom is YourName en het is de standaard TextBox (dataGridViewTextBoxColumn). Stel de koptekst ook in op uw naam. Maak de tweede kolom Leeftijd en gebruik een ComboBox. De derde kolom is toegestaan ​​en is een CheckBox-kolom.

Na het toevoegen van alle drie zou u een rij van drie kolommen moeten zien met een combinatie in de middelste (Leeftijd) en een selectievakje in de kolom Toegestaan. Als u op DataGridView klikt, moet u in de eigenschappencontrole kolommen lokaliseren en op (verzameling) klikken. Dit opent een dialoogvenster waarin u eigenschappen voor elke kolom kunt instellen, zoals individuele celkleuren, knopinfo, breedte, minimale breedte enz. Als u compileert en uitvoert, zult u merken dat u de kolombreedten en de runtime kunt wijzigen. In de eigenschappencontrole voor de belangrijkste DataGridView kunt u AllowUser instellen op resizeColumns op false om dat te voorkomen.

We gaan rijen toevoegen aan het DataGridView-besturingselement in code en ex3.cs in het voorbeeldbestand heeft deze code. Te beginnen met het toevoegen van een TextEdit-box, een ComboBox en een knop aan het formulier met de DataGridView erop. Stel de eigenschap DataGridView AllowUserto AddRows in op false. Ik gebruik ook labels en noemde de combobox cbAges, de knop btnAddRow en de TextBox tbName. Ik heb ook een sluitknop voor het formulier toegevoegd en erop dubbelklikt om een ​​btnClose_Click-eventhandlerskelet te genereren. Door daar het woord Close () toe te voegen, werkt dat.

Standaard is de eigenschap Rijknop toevoegen ingeschakeld ingesteld op false bij het starten. We willen geen rijen toevoegen aan de DataGridView, tenzij er tekst is in zowel het vak Name TextEdit als de ComboBox. Ik creëerde de methode CheckAddButton en genereerde vervolgens een gebeurtenisverwerker Verlof voor het tekstvak Naam Tekst door te dubbelklikken naast het woord Verlof in de Eigenschappen toen het de gebeurtenissen weergaf. Het vak Eigenschappen toont dit in de bovenstaande afbeelding. Standaard toont het vak Eigenschappen eigenschappen, maar u kunt gebeurtenisafhandelaars zien door op de bliksemknop te klikken.

Je zou in plaats daarvan de TextChanged-gebeurtenis kunnen gebruiken, hoewel dit de CheckAddButton () zal aanroepen methode voor elke toetsaanslag in plaats van wanneer de controle wordt verlaten, d.w.z. wanneer een andere controle wint focus. Op de Ages Combo gebruikte ik de TextChanged-gebeurtenis, maar ik koos de tbName_Leave-eventhandler in plaats van te dubbelklikken om een ​​nieuwe eventhandler te maken.

Niet alle gebeurtenissen zijn compatibel omdat sommige gebeurtenissen extra parameters bevatten, maar als u een eerder gegenereerde handler kunt zien, dan kunt u deze gebruiken. Het is meestal een kwestie van voorkeur, je kunt een aparte event handler hebben voor elke controle die je bent eventhandlers gebruiken of delen (zoals ik deed) wanneer ze een gemeenschappelijke gebeurtenishandtekening hebben, d.w.z. de parameters zijn de dezelfde.

Ik hernoemde de DataGridView-component voor de beknoptheid tot dGView en dubbelklik op de AddRow om een ​​skelet voor een event-handler te genereren. Deze code hieronder voegt een nieuwe lege rij toe, verkrijgt die rijenindex (het is RowCount-1 zoals het zojuist is toegevoegd en RowCount is 0 gebaseerd) en opent vervolgens die rij via zijn index en stelt de waarden in de cellen in die rij in voor de kolommen YourName en Leeftijd.

Bij het ontwerpen van een formulier moet u denken in termen van containers en controles en welke groepen controles bij elkaar moeten worden gehouden. In westerse culturen lezen mensen hoe dan ook van linksboven naar rechtsonder, dus maak het gemakkelijker om op die manier te lezen.

Een container is een van de besturingselementen die andere besturingselementen kunnen bevatten. Die in de Toolbox zijn onder meer het paneel, FlowLayoutpanel, SplitContainer, TabControl en TableLayoutPanel. Als u de toolbox niet kunt zien, gebruik dan het menu Beeld en u zult het vinden. Containers houden de bedieningselementen bij elkaar en als u de container verplaatst of het formaat ervan wijzigt, heeft dit invloed op de positionering van de bedieningselementen. Beweeg gewoon de knoppen over de container in de Form Designer en hij zal herkennen dat de container nu de leiding heeft.

Een paneel is vergelijkbaar met een GroupBox, maar een GroupBox kan niet scrollen, maar kan een bijschrift weergeven en heeft standaard een rand. Panelen kunnen randen hebben, maar niet standaard. Ik gebruik GroupBoxes omdat ze er mooier uitzien en dit is belangrijk omdat:

Panelen zijn ook handig voor het groeperen van containers, dus het kan zijn dat u twee of meer GroupBoxen op een paneel heeft.

Hier is een tip voor het werken met containers. Zet een gesplitste container neer op een formulier. Klik op het linkerpaneel en vervolgens op het rechterpaneel. Probeer nu de SplitContainer uit het formulier te verwijderen. Het is moeilijk totdat u met de rechtermuisknop op een van de panelen klikt en vervolgens op Selecteer SplitContainer1 klikt. Zodra alles is geselecteerd, kunt u het verwijderen. Een andere manier die van toepassing is op alle bedieningselementen en containers is druk op de Esc-toets om de ouder te selecteren.

Containers kunnen ook in elkaar nestelen. Sleep gewoon een kleine bovenop een grotere en je ziet kort een dunne verticale lijn om aan te geven dat de ene nu in de andere zit. Wanneer u de bovenliggende container sleept, wordt het kind ermee verplaatst. Voorbeeld 5 laat dit zien. Standaard bevindt het lichtbruine paneel zich niet in de container, dus wanneer u op de verplaatsknop klikt, wordt de GroupBox verplaatst, maar het paneel niet. Sleep nu het paneel over de GroupBox zodat het volledig in de Groupbox zit. Wanneer u deze keer compileert en uitvoert, worden beide samen verplaatst als u op de knop Verplaatsen klikt.

Een TableLayoutpanel is een interessante container. Het is een tabelstructuur die is georganiseerd als een 2D-raster met cellen, waarbij elke cel slechts één besturingselement bevat. Je kunt niet meer dan één besturingselement in een cel hebben. U kunt specificeren hoe de tabel groeit wanneer er meer besturingselementen worden toegevoegd of zelfs als deze niet groeit, het lijkt gemodelleerd naar een HTML-tabel omdat cellen kolommen of rijen kunnen omspannen. Zelfs het verankeringsgedrag van kindercontroles in de container hangt af van de marge- en opvulinstellingen. We zullen meer zien over ankers op de volgende pagina.

In Ex6.cs ben ik bijvoorbeeld begonnen met een eenvoudige tabel met twee kolommen en gespecificeerd via het dialoogvenster Besturing en rijstijlen (selecteer het besturingselement en klik op het kleine naar rechts wijzende driehoek in de rechterbovenhoek om een ​​lijst met taken te zien en op de laatste te klikken) dat de linkerkolom 40% is en de rechterkolom 60% van de breedte. Hiermee kunt u kolombreedtes specificeren in absolute pixeltermen, in percentage of u kunt het gewoon AutoSize laten. Een snellere manier om naar dit dialoogvenster te gaan, is door op de verzameling naast Kolommen in het eigenschappenvenster te klikken.

Ik heb een AddRow-knop toegevoegd en de eigenschap GrowStyle gelaten met de standaardwaarde AddRows. Als de tafel vol raakt, wordt er nog een rij toegevoegd. Als alternatief kunt u de waarden ervan instellen op AddColumns en FixedSize, zodat het niet meer kan groeien. Wanneer u in Ex6 op de knop Besturingselementen toevoegen klikt, wordt drie keer de methode AddLabel () aangeroepen en eenmaal AddCheckBox (). Elke methode maakt een instantie van het besturingselement en roept vervolgens tblPanel aan. Bediening. Toevoegen () Nadat de 2e controle is toegevoegd, zorgt de derde controle ervoor dat de tabel groeit. De afbeelding toont het nadat eenmaal op de knop Add Control is geklikt.

Als u zich afvraagt ​​waar de standaardwaarden vandaan komen in de AddCheckbox () en AddLabel () -methoden die ik aanroep, was de controle oorspronkelijk handmatig toegevoegd aan de tabel in de ontwerper en vervolgens de code om deze te maken en te initialiseren, werd van daaruit gekopieerd regio. U vindt de initialisatiecode in de aanroep InitializeComponent-methode zodra u op de + links van de onderstaande regio klikt:

U kunt meerdere bedieningselementen tegelijkertijd selecteren door de Shift-toets ingedrukt te houden wanneer u de tweede en volgende bedieningselementen selecteert, zelfs besturingselementen van verschillende typen. Het eigenschappenvenster toont alleen de eigenschappen die beide gemeen hebben, dus u kunt ze allemaal instellen op dezelfde grootte, kleur en tekstvelden enz. Zelfs dezelfde eventhandlers kunnen aan meerdere bedieningselementen worden toegewezen.

Afhankelijk van het gebruik worden sommige formulieren vaak door de gebruiker verkleind. Niets ziet er erger uit dan het formaat van een formulier te wijzigen en de bedieningselementen op dezelfde positie te houden. Alle bedieningselementen hebben ankers waarmee u ze aan de 4 randen kunt "bevestigen", zodat het besturingselement beweegt of uitrekt wanneer een bevestigde rand wordt verplaatst. Dit leidt tot het volgende gedrag wanneer een formulier vanaf de rechterkant wordt uitgerekt:

Voor knoppen zoals Sluiten die traditioneel rechtsonder staan, is gedrag 3 nodig. ListViews en DataGridViews zijn het beste met 2 als het aantal kolommen voldoende is om het formulier te overlopen en moet worden gescrold). De ankers boven en links zijn de standaard. Het eigenschappenvenster bevat een handige kleine editor die lijkt op de Engelse vlag. Klik gewoon op een van de balken (twee horizontaal en twee verticaal) om het juiste anker in te stellen of te wissen, zoals weergegeven in de bovenstaande afbeelding.

Een eigenschap die niet veel wordt genoemd, is de eigenschap Tag en toch kan deze ongelooflijk nuttig zijn. In het eigenschappenvenster kunt u alleen tekst toewijzen, maar in uw code kunt u elke waarde hebben die uit Object afdaalt.

Ik heb Tag gebruikt om een ​​heel object vast te houden terwijl ik maar een paar van zijn eigenschappen in een ListView liet zien. U wilt bijvoorbeeld mogelijk alleen een klantnaam en nummer weergeven in een lijst met klantoverzichten. Maar klik met de rechtermuisknop op de geselecteerde klant en open vervolgens een formulier met alle klantgegevens. Dit is gemakkelijk als u de klantenlijst opbouwt door alle klantgegevens in het geheugen te lezen en een verwijzing naar het Customer Class-object in de tag toe te wijzen. Alle bedieningselementen hebben een tag.

Een TabControl is een handige manier om ruimte te besparen door meerdere tabbladen te hebben. Elk tabblad kan een pictogram of tekst bevatten en u kunt elk tabblad selecteren en de bedieningselementen weergeven. De TabControl is een container maar bevat alleen TabPages. Elke TabPage is ook een container waaraan normale bedieningselementen kunnen worden toegevoegd.

In voorbeeld x7.cs, ik heb een paneel met twee tabbladen gemaakt met het eerste tabblad genaamd Controls met drie knoppen en een selectievakje erop. De tweede tabbladpagina heeft het label Logs en wordt gebruikt om alle gelogde acties weer te geven, waaronder het klikken op een knop of het omschakelen van een selectievakje. Een methode genaamd Log () wordt aangeroepen om elke knopklik enz. Te loggen. Het voegt de meegeleverde string toe aan een ListBox.

Ik heb ook op de gebruikelijke manier twee pop-upmenu-items met de rechtermuisknop toegevoegd aan de TabControl. Voeg eerst een ContextMenuStrip toe aan het formulier en stel deze in de eigenschap ContextStripMenu van de TabControl in. De twee menukeuzes zijn Nieuwe pagina toevoegen en Deze pagina verwijderen. Ik heb echter de verwijdering van de pagina beperkt, zodat alleen nieuw toegevoegde tabbladpagina's kunnen worden verwijderd en niet de originele twee.

Dit is eenvoudig, maak gewoon een nieuwe tabbladpagina, geef het een tekstbijschrift voor het tabblad en voeg het vervolgens toe aan de verzameling tabpagina's van de tabbladen TabControl

Een pagina verwijderen is gewoon een kwestie van TabPages aanroepen. RemoveAt () met behulp van de tabbladen. SelectedIndex om het momenteel geselecteerde tabblad op te halen.

In deze tutorial hebben we gezien hoe sommige van de meer geavanceerde bedieningselementen werken en hoe ze te gebruiken. In de volgende tutorial ga ik verder met het GUI-thema en kijk naar de achtergrondwerkthread en laat zien hoe je het kunt gebruiken.

instagram story viewer