Delen via


Overzicht van aangepaste XAML-panelen

Een paneel is een object dat een indelingsgedrag biedt voor onderliggende elementen die het bevat, wanneer het XAML-indelingssysteem (Extensible Application Markup Language) wordt uitgevoerd en de gebruikersinterface van uw app wordt weergegeven.

Belangrijke API's: Panel, ArrangeOverride, MeasureOverride

U kunt aangepaste panelen definiëren voor de XAML-indeling door een aangepaste klasse te afleiden uit het paneel klasse. U levert gedrag voor uw paneel door de MeasureOverride- en ArrangeOverride-te overschrijven, door het leveren van logica die de subelementen meet en rangschikt.

De Panel Basisklasse

Als u een aangepaste deelvensterklasse wilt definiëren, kunt u rechtstreeks afleiden van de Panelklasse of afleiden van een van de praktische paneelklassen die niet zijn verzegeld, zoals Grid of StackPanelklasse. Het is gemakkelijker om af te leiden van Paneel, omdat het lastig kan zijn om de bestaande indelingslogica van een paneel te omzeilen dat al indelingsgedrag heeft. Een deelvenster met gedrag kan ook bestaande eigenschappen hebben die niet relevant zijn voor de indelingsfuncties van uw deelvenster.

Vanuit paneelerft uw aangepaste paneel de volgende API's:

  • De eigenschap Children.
  • De Background, ChildrenTransitions en IsItemsHost eigenschappen, en de identificeerders van afhankelijkheidseigenschappen. Geen van deze eigenschappen is virtueel, dus u overschrijft of vervangt ze meestal niet. U hebt deze eigenschappen doorgaans niet nodig voor aangepaste deelvensterscenario's, zelfs niet voor het lezen van waarden.
  • De layout-overschrijvingsmethoden MeasureOverride en ArrangeOverride. Deze zijn oorspronkelijk gedefinieerd door FrameworkElement. De basis Panel klasse overschrijft deze niet, maar praktische panelen zoals Grid hebben wel override-implementaties die in native code zijn geschreven en door het systeem worden uitgevoerd. Het bieden van nieuwe (of additieve) implementaties voor ArrangeOverride en MeasureOverride is het grootste deel van de inspanningen die u nodig hebt om een aangepast paneel te definiëren.
  • Alle andere API's van FrameworkElement, UIElement en DependencyObject, zoals Height, Visibility enzovoort. Soms verwijst u naar waarden van deze eigenschappen in de indelingsoverschrijvingen, maar ze zijn niet virtueel, zodat u ze meestal niet overschrijft of vervangt.

Deze focus is hier om XAML-indelingsconcepten te beschrijven, zodat u rekening kunt houden met alle mogelijkheden voor hoe een aangepast paneel zich kan gedragen en moet werken in de indeling. Zie BoxPanel, een voorbeeld van een aangepast paneel, als u liever meteen in de praktijk aan de slag gaat en een voorbeeld van een implementatie van een aangepast paneel wilt zien.

De eigenschap Children

De Children eigenschap is relevant voor een aangepast deelvenster, omdat alle klassen die zijn afgeleid van Panel de eigenschap Children gebruiken als de plek om hun onderliggende elementen in een verzameling op te slaan. Children wordt aangewezen als de XAML-inhoudseigenschap voor de Panel-klasse, en alle klassen die zijn afgeleid van Panel kunnen het gedrag van de XAML-inhoudseigenschap overnemen. Als een eigenschap is aangewezen als de XAML-inhoudseigenschap, betekent dit dat XAML-opmaak een eigenschapselement kan weglaten bij het opgeven van die eigenschap in opmaak, en dat de waarden worden ingesteld als directe opmaakkinderen (de 'inhoud'). Als u bijvoorbeeld een klasse afleiden met de naam CustomPanel van Panel waarmee geen nieuw gedrag wordt gedefinieerd, kunt u deze markering nog steeds gebruiken:

<local:CustomPanel>
  <Button Name="button1"/>
  <Button Name="button2"/>
</local:CustomPanel>

Wanneer een XAML-parser deze markering leest, is Onderliggende bekend de eigenschap XAML-inhoud voor alle Deelvenster afgeleide typen, zodat de parser de twee Knop elementen toevoegt aan de UIElementCollection- waarde van de eigenschap Onderliggende elementen. De inhoudseigenschap XAML vereenvoudigt een gestroomlijnde relatie tussen bovenliggende en onderliggende elementen in de XAML-opmaak voor een UI-definitie. Zie de XAML-syntaxishandleidingvoor meer informatie over inhoudseigenschappen van XAML en hoe verzamelingseigenschappen worden ingevuld wanneer XAML wordt geparseerd.

Het verzamelingstype dat de waarde van de eigenschap Children behoudt, is de klasse UIElementCollection. UIElementCollection is een sterk getypte verzameling die gebruikmaakt van UIElement als het afgedwongen itemtype. UIElement is een basistype dat wordt overgenomen door honderden praktische UI-elementtypen, zodat de type-enforcement hier opzettelijk soepel is. Maar het dwingt wel af dat u geen Brush- als een direct onderliggend element van een Paneelkunt hebben. Dit betekent in het algemeen dat alleen elementen die naar verwachting zichtbaar zijn in de gebruikersinterface en deelnemen aan de indeling worden gevonden als onderliggende elementen in een Paneel.

Normaal gesproken accepteert een aangepast deelvenster elk UIElement kindelement volgens een XAML-definitie, door simpelweg de kenmerken van de eigenschap Kinderen as-iste gebruiken. Als geavanceerd scenario kunt u verdere typecontrole van onderliggende elementen ondersteunen wanneer u de verzameling in de indeling overschrijft.

Naast het doorlopen van de verzameling Kinderen in de overschrijvingen, kan uw paneellogica ook worden beïnvloed door Children.Count. Mogelijk hebt u logica die ten minste gedeeltelijk ruimte toedeelt op basis van het aantal items, in plaats van de gewenste grootten en de andere kenmerken van afzonderlijke items.

De indelingsmethoden overschrijven

Het basismodel voor de indelingsoverschrijvingsmethoden (MeasureOverride en ArrangeOverride) is dat ze door alle kind-elementen moeten itereren en de specifieke indelingsmethode van elk element moeten aanroepen. De eerste indelingscyclus begint wanneer het XAML-indelingssysteem de visual voor het hoofdvenster instelt. Omdat elke ouder lay-out aanroept op zijn kinderen, wordt hiermee een aanroep naar lay-outmethoden doorgegeven aan elk mogelijk UI-element dat deel moet uitmaken van een lay-out. In de XAML-indeling zijn er twee fasen: meting en vervolgens rangschikken.

Je krijgt geen ingebouwd gedrag van de lay-outmethodes voor MeasureOverride- en ArrangeOverride- vanuit de basis Panel klasse. Items in Kinderen worden niet automatisch gerenderd als onderdeel van de XAML-visuele boom. Het is aan u om de items bekend te maken bij het lay-outproces door lay-outmethoden aan te roepen voor elk van de items die u in Onderliggende items vindt, via een lay-outpassage binnen uw MeasureOverride en ArrangeOverride implementaties.

Er is geen reden om basisimplementaties aan te roepen in overschrijvingen van de lay-out, tenzij u uw eigen overerving hebt. De systeemeigen methoden voor lay-outgedrag (indien aanwezig) worden in elk geval uitgevoerd, en het niet aanroepen van de basisimplementatie van overschrijvingen verhindert het systeemeigen gedrag niet.

Tijdens de meetronde vraagt de lay-outlogica met behulp van de methode Measure de gewenste grootte op van elk onderliggend element. Als u de Measure methode aanroept, wordt de waarde voor de eigenschap DesiredSize ingesteld. De MeasureOverride retourwaarde is de gewenste grootte voor het deelvenster zelf.

Tijdens de rangschikkpas worden de posities en grootten van onderliggende elementen bepaald in de x-y-ruimte en wordt de indelingssamenstelling voorbereid voor rendering. Uw code moet Arrange oproepen voor elk kindelement in Children, zodat het indelingssysteem detecteert dat het element bij de indeling hoort. De Rangschikken aanroep is een voorloper van compositie en rendering; het informeert het indelingssysteem waar dat element naartoe gaat wanneer de compositie wordt doorgegeven voor rendering.

Veel eigenschappen en waarden dragen bij aan de werking van de lay-outlogica tijdens runtime. Een manier om het indelingsproces te benaderen is dat de elementen zonder kinderen (doorgaans het diepst geneste element in de gebruikersinterface) degenen zijn die metingen het eerst kunnen voltooien. Ze hebben geen afhankelijkheden van kindelementen die van invloed zijn op de gewenste grootte. Ze kunnen hun eigen gewenste grootten hebben en dit zijn suggesties voor grootten totdat de indeling daadwerkelijk plaatsvindt. Vervolgens wordt er doorgegaan met de meting door het doorlopen van de visuele boomstructuur totdat de metingen van het hoofdelement voltooid zijn, zodat alle metingen kunnen worden voltooid.

De kandidaatindeling moet binnen het huidige app-venster passen, anders zullen delen van de gebruikersinterface worden afgesneden. Panelen zijn vaak de plaats waar de kniplogica wordt bepaald. Paneellogica kan bepalen welke grootte beschikbaar is in de MeasureOverride implementatie en moet mogelijk de groottebeperkingen naar de kinderen pushen en ruimte verdelen tussen kinderen, zodat alles zo goed mogelijk past. Het resultaat van de indeling is idealiter iets dat gebruikmaakt van verschillende eigenschappen van alle onderdelen van de indeling, maar nog steeds binnen het app-venster past. Hiervoor is zowel een goede implementatie vereist voor lay-outlogica van de panelen, als ook een verstandig UI-ontwerp op basis van app-code die een gebruikersinterface bouwt met behulp van dat paneel. Het ontwerp van een paneel zal er nooit goed uitzien als het algehele UI-ontwerp meer subelementen bevat dan er in de app passen.

Een groot deel van wat ervoor zorgt dat het indelingssysteem werkt, is dat elk element dat is gebaseerd op FrameworkElement al zijn eigen inherente gedrag heeft wanneer het fungeert als een kindelement in een container. Er zijn bijvoorbeeld verschillende API's van FrameworkElement die het gedrag van de indeling informeren of die nodig zijn om de indeling helemaal te laten werken. Deze omvatten:

MeasureOverride

De methode MeasureOverride heeft een retourwaarde die door het indelingssysteem wordt gebruikt als de begingrootte DesiredSize voor het paneel zelf, wanneer de methode Measure door de bovenliggende indeling op het paneel wordt aangeroepen. De logische keuzes binnen de methode zijn net zo belangrijk als wat deze retourneert en de logica beïnvloedt vaak welke waarde wordt geretourneerd.

Alle MeasureOverride--implementaties moeten itereren over de onderliggende elementenen de methode Measure aanroepen voor elk kindelement. Als u de Measure methode aanroept, wordt de waarde voor de eigenschap DesiredSize ingesteld. Dit kan aangeven hoeveel ruimte het paneel zelf nodig heeft, evenals hoe die ruimte wordt verdeeld over de elementen of op maat gemaakt wordt voor een bepaald subelement.

Hier volgt een zeer eenvoudig skelet van een MeasureOverride methode:

protected override Size MeasureOverride(Size availableSize)
{
    Size returnSize; //TODO might return availableSize, might do something else
     
    //loop through each Child, call Measure on each
    foreach (UIElement child in Children)
    {
        child.Measure(new Size()); // TODO determine how much space the panel allots for this child, that's what you pass to Measure
        Size childDesiredSize = child.DesiredSize; //TODO determine how the returned Size is influenced by each child's DesiredSize
        //TODO, logic if passed-in Size and net DesiredSize are different, does that matter?
    }
    return returnSize;
}

Elementen hebben vaak een natuurlijke grootte op het moment dat ze klaar zijn voor indeling. Nadat de maatregel is uitgevoerd, kan de DesiredSize aangeven dat dit de natuurlijke grootte is, als de doorgegeven availableSize voor Measure kleiner was. Als de natuurlijke grootte groter is dan de beschikbareGrootte die u hebt doorgegeven voor het Meten, wordt de GewensteGrootte beperkt tot de beschikbareGrootte. Zo gedraagt de interne implementatie van Maatregelzich, en uw indelingsoverrides moeten dat gedrag in rekening houden.

Sommige elementen hebben geen natuurlijke grootte, omdat ze automatische waarden voor Hoogte en Breedtehebben. Deze elementen gebruiken de volledige availableSize, omdat dat is wat een Auto waarde vertegenwoordigt: het element groot maken tot de maximaal beschikbare grootte, die de onmiddellijke bovenliggende indeling communiceert door Measure aan te roepen met availableSize. In de praktijk is er altijd een meting waaraan een gebruikersinterface wordt aangepast (zelfs als dat het venster op het hoogste niveau is). Uiteindelijk worden bij de meetpas alle Auto-waarden omgezet in bovenliggende beperkingen en krijgen alle Auto-waarde-elementen echte metingen (die u kunt verkrijgen door ActualWidth- en ActualHeightte controleren nadat de indeling is voltooid).

Het is toegestaan om een grootte door te geven aan Measure die ten minste één oneindige dimensie heeft, om aan te geven dat het paneel kan proberen zich aan te passen aan de afmetingen van zijn inhoud. Elk onderliggend element dat wordt gemeten, stelt de DesiredSize waarde in op basis van de natuurlijke grootte. Tijdens de indelingsstap ordent het paneel doorgaans gebruikmakend van die grootte.

Tekstelementen zoals TextBlock- hebben een berekende ActualWidth- en ActualHeight op basis van hun tekenreeks- en teksteigenschappen, zelfs als er geen Height of Width waarde is ingesteld, en moeten deze dimensies worden gerespecteerd door uw paneellogica. Tekst knippen is een bijzonder slechte gebruikersinterface-ervaring.

Zelfs als uw implementatie niet gebruikmaakt van de gewenste groottemetingen, kunt u het beste de methode meting aanroepen voor elk onderliggend element, omdat er interne en systeemeigen gedragingen zijn die worden geactiveerd door Meting wordt aangeroepen. Als u een element wilt laten deelnemen aan de indeling, moet de Measure op elk onderliggend element worden aangeroepen tijdens de measure-pass en de methode Arrange worden aangeroepen tijdens de arrange-pass. Als u deze methoden aanroept, worden interne vlaggen voor het object ingesteld en worden waarden (zoals de eigenschap DesiredSize) ingevuld die de indelingslogica van het systeem nodig heeft wanneer de visualstructuur wordt gebouwd en de gebruikersinterface wordt weergegeven.

De MeasureOverride terugkeerwaarde is gebaseerd op de logica van het paneel dat de DesiredSize of andere grootte-overwegingen interpreteert voor elk van de kinder-elementen in Children wanneer Measure op hen wordt aangeroepen. Wat u met de DesiredSize waarden van de kinderen doet en hoe de MeasureOverride retourwaarde ze moet gebruiken, is afhankelijk van de interpretatie van uw eigen logica. Meestal telt u de waarden niet op zonder wijziging, doordat de invoer van MeasureOverride vaak een vaste beschikbare grootte is die door de ouder van het paneel wordt voorgesteld. Als u deze grootte overschrijdt, kan het paneel worden afgesneden. Meestal vergelijkt u de totale grootte van kinderen met de beschikbare grootte van het paneel en kunt u indien nodig aanpassingen aanbrengen.

Tips en richtlijnen

  • In het ideale geval moet een aangepast paneel geschikt zijn om de eerste echte visuele component in een UI-samenstelling te zijn, mogelijk op een niveau direct onder Page, UserControl, of een ander element dat de wortel van de XAML-pagina is. In MeasureOverride implementaties, retourneer dan niet regelmatig de invoer Grootte zonder de waarden te controleren. Als de geretourneerde Grootte een Infinity-waarde bevat, kan dit uitzonderingen veroorzaken in layout-logica tijdens runtime. Een Infinity-waarde kan afkomstig zijn uit het hoofd-app-venster, dat schuifbaar is en dus geen maximale hoogte heeft. Andere schuifbare inhoud kan hetzelfde gedrag hebben.
  • Een andere veelvoorkomende fout in MeasureOverride--implementaties is het retourneren van een nieuwe standaardinstelling Grootte (waarden voor hoogte en breedte zijn 0). U kunt beginnen met die waarde, en het zou zelfs de correcte waarde kunnen zijn als uw paneel bepaalt dat geen van de kinderen moet worden weergegeven. Maar een standaard Grootte zorgt ervoor dat uw paneel niet correct wordt geschaald door de host. Er wordt geen ruimte in de gebruikersinterface aangevraagd, en krijgt daarom geen ruimte en wordt niet weergegeven. Al uw paneelcode werkt anders mogelijk prima, maar u ziet het paneel of de inhoud ervan nog steeds niet als deze is samengesteld met een hoogte van nul, nulbreedte.
  • Vermijd in de overschrijvingen de verleiding om onderliggende elementen te casten naar FrameworkElement en gebruik geen eigenschappen die worden berekend als gevolg van de indeling, met name ActualWidth en ActualHeight. Voor de meest voorkomende scenario's kunt u de logica baseren op de DesiredSize-waarde van het kind en hebt u geen van de Height of Width gerelateerde eigenschappen van een kind-element nodig. Voor gespecialiseerde gevallen, waarbij u het type element kent en aanvullende informatie hebt, bijvoorbeeld de natuurlijke grootte van een afbeeldingsbestand, kunt u de gespecialiseerde informatie van uw element gebruiken omdat het geen waarde is die actief wordt gewijzigd door indelingssystemen. Het opnemen van door indeling berekende eigenschappen als onderdeel van indelingslogica verhoogt het risico van het definiëren van een onbedoelde indelingslus. Deze lussen veroorzaken een situatie waarin er geen geldige indeling kan worden gemaakt en het systeem kan een LayoutCycleException genereren als de lus niet kan worden hersteld.
  • Panelen verdelen doorgaans hun beschikbare ruimte tussen meerdere onderliggende elementen, hoewel de manier waarop de ruimte wordt verdeeld kan variëren. Grid bijvoorbeeld indelingslogica implementeert die gebruikmaakt van de RowDefinition en ColumnDefinition waarden om de ruimte te verdelen in de Raster cellen, waarbij zowel stergrootte als pixelwaarden worden ondersteund. Als het pixelwaarden betreft, is de grootte die beschikbaar is voor elk kind al bekend, zodat dit wordt doorgegeven als invoergrootte voor een rasterstijl meting.
  • Panelen zelf kunnen gereserveerde ruimte voor opvulling tussen items introduceren. Als u dit doet, zorg er dan voor dat u de parameters zichtbaar maakt als een eigenschap die verschilt van marge of enige opvullingseigenschap.
  • Elementen kunnen waarden hebben voor hun ActualWidth-- en ActualHeight--eigenschappen, gebaseerd op een eerdere layoutpass. Als waarden veranderen, kan de gebruikersinterfacecode van de app handlers plaatsen voor LayoutUpdated op elementen wanneer speciale logica moet worden uitgevoerd, maar paneellogica hoeft doorgaans niet op wijzigingen te controleren met gebeurtenisafhandeling. Het indelingssysteem stelt al vast wanneer de lay-out opnieuw moet worden uitgevoerd, omdat een eigenschap die relevant is voor de indeling de waarde heeft gewijzigd en de MeasureOverride- of ArrangeOverride- automatisch worden aangeroepen in de juiste omstandigheden.

SchikkenOverschrijven

De methode ArrangeOverride heeft een Grootte retourwaarde die door het indelingssysteem wordt gebruikt bij het weergeven van het deelvenster zelf, wanneer de methode Rangschikken wordt aangeroepen op het deelvenster door de bovenliggende indeling. Het is gebruikelijk dat de invoer voltooien en de ArrangeOverride geretourneerd Grootte hetzelfde zijn. Als dat niet zo is, betekent dit dat het deelvenster probeert zichzelf een andere grootte te geven dan wat beschikbaar is volgens de andere deelnemers aan de indeling. De uiteindelijke grootte was gebaseerd op het eerder uitvoeren van de metingsdoorgang van de lay-out via uw paneelcode, dus daarom is het retourneren van een andere grootte niet gebruikelijk: dit betekent dat u opzettelijk meetlogica negeert.

Retourneer geen Size met een Infinity-onderdeel. Als u een dergelijke Grootte probeert te gebruiken een uitzondering op de interne indeling genereert.

Alle ArrangeOverride--implementaties moeten Childrendoorlopen en de Arrange-methode voor elk kindelement aanroepen. Net zoals Measureheeft Arrange geen retourwaarde. In tegenstelling tot Meting, wordt er geen berekende eigenschap als resultaat ingesteld (echter, het betreffende element activeert meestal een LayoutUpdated gebeurtenis).

Hier volgt een zeer eenvoudig skelet van een ArrangeOverride methode:

protected override Size ArrangeOverride(Size finalSize)
{
    //loop through each Child, call Arrange on each
    foreach (UIElement child in Children)
    {
        Point anchorPoint = new Point(); //TODO more logic for topleft corner placement in your panel
       // for this child, and based on finalSize or other internal state of your panel
        child.Arrange(new Rect(anchorPoint, child.DesiredSize)); //OR, set a different Size 
    }
    return finalSize; //OR, return a different Size, but that's rare
}

Het rangschikken van de indeling kan gebeuren zonder vooraf te worden gegaan door een metingspas. Dit gebeurt echter alleen wanneer het indelingssysteem heeft vastgesteld dat er geen eigenschappen zijn gewijzigd die de vorige metingen zouden hebben beïnvloed. Als een uitlijning bijvoorbeeld verandert, hoeft u dat specifieke element niet opnieuw te meten, omdat de DesiredSize- niet zou veranderen wanneer de uitlijningskeuze verandert. Aan de andere kant, als ActualHeight wijzigt aan een element in een lay-out, is een nieuwe meetcyclus nodig. Het indelingssysteem detecteert automatisch echte metingswijzigingen, herhaalt de meetpass en voert daarna nog een rangschikpass uit.

De invoer voor Arrange accepteert een Rect-waarde. De meest voorkomende manier om deze Rect te maken, is de constructor te gebruiken met een invoer van een Punt en een Grootte. De Punt is het punt waar de linkerbovenhoek van het begrenzingsvak voor het element moet worden geplaatst. De Grootte zijn de dimensies die worden gebruikt om dat specifieke element weer te geven. Vaak gebruikt u de DesiredSize voor dat element als deze Grootte waarde, omdat het vaststellen van de DesiredSize voor alle elementen die betrokken zijn bij de opmaak, het doel was van de meetbewerking van de opmaak. (De metingspas bepaalt de grootte van de elementen op een iteratieve manier, zodat het indelingssysteem kan optimaliseren hoe elementen worden geplaatst zodra deze bij de rangschikkende pas komen.)

Wat doorgaans varieert tussen ArrangeOverride--implementaties, is de logica waarmee het paneel het Punt onderdeel bepaalt van de wijze waarop elk kind wordt gerangschikt. Een absoluut plaatsingspaneel zoals Canvas gebruikt de expliciete plaatsingsgegevens die het van elk element ophaalt via Canvas.Left en Canvas.Top waarden. Een ruimtescheidingspaneel zoals Raster zou wiskundige bewerkingen hebben die de beschikbare ruimte in cellen hebben verdeeld en elke cel een x-y-waarde zou hebben voor waar de inhoud moet worden geplaatst en gerangschikt. Een adaptief paneel zoals StackPanel kan zich uitbreiden om inhoud in de richtingsdimensie aan te passen.

Er zijn nog steeds extra positioneringsinvloeden op elementen in de opmaak, naast wat u rechtstreeks beheert en doorgeeft aan Rangschikken. Deze zijn afkomstig van de interne en systeemeigen implementatie van Rangschikken, die gemeenschappelijk is voor alle FrameworkElement afgeleide typen en wordt uitgebreid door enkele andere typen, zoals tekstelementen. Elementen kunnen bijvoorbeeld marges en uitlijning hebben en sommige elementen kunnen opvulling hebben. Deze eigenschappen communiceren vaak. Zie Uitlijning, marge en opvullingvoor meer informatie.

Panelen en besturingselementen

Vermijd het plaatsen van functionaliteit in een aangepast paneel dat in plaats daarvan moet worden gebouwd als een aangepast besturingselement. De rol van een deelvenster is het presenteren van inhoud van onderliggende elementen die erin aanwezig is, als een functie van indeling die automatisch plaatsvindt. Het deelvenster kan decoraties toevoegen aan inhoud (vergelijkbaar met de manier waarop een Rand de rand rond het element dat het presenteert) toevoegt) of andere opvullingsgerelateerde aanpassingen uitvoeren. Maar u moet niet verder gaan dan dat bij het uitbreiden van de output van de visuele boom, voorbij het rapporteren en gebruiken van informatie van de onderliggende elementen.

Als er interactie is die toegankelijk is voor de gebruiker, moet u een aangepast besturingselement schrijven, niet een paneel. Een paneel mag bijvoorbeeld geen scrolling viewports toevoegen aan inhoud die het presenteert, zelfs als het doel is om het knippen te voorkomen, omdat de schuifbalken, duimen enzovoort interactieve besturingsonderdelen zijn. (Inhoud kan immers schuifbalken bevatten, maar u moet dat laten over aan de logica van het kind. Dwing dit niet af door schuiven toe te voegen als indelingsbewerking.) U kunt een besturingselement maken en ook een aangepast paneel schrijven dat een belangrijke rol speelt in de visuele structuur van dat besturingselement, als het gaat om het presenteren van inhoud in dat besturingselement. Het besturingselement en het paneel moeten echter afzonderlijke codeobjecten zijn.

Een van de redenen waarom het onderscheid tussen het configuratiescherm en het paneel belangrijk is, is vanwege Microsoft UI Automation en toegankelijkheid. Panelen bieden een visueel indelingsgedrag, geen logisch gedrag. Hoe een UI-element visueel wordt weergegeven, is geen aspect van de gebruikersinterface die doorgaans belangrijk is voor toegankelijkheidsscenario's. Toegankelijkheid gaat over het blootstellen van de onderdelen van een app die logisch belangrijk zijn voor het begrijpen van een gebruikersinterface. Wanneer interactie is vereist, moeten besturingselementen de interactiemogelijkheden beschikbaar maken voor de UI Automation-infrastructuur. Voor meer informatie, zie Aangepaste automatiseringspeers.

Andere indelings-API

Er zijn enkele andere API's die deel uitmaken van het indelingssysteem, maar die niet worden gedeclareerd door Paneel. U kunt deze gebruiken in een panel-implementatie of in een aangepast besturingselement dat gebruikmaakt van panelen.

  • UpdateLayout, InvalidateMeasureen InvalidateArrange zijn methoden die een lay-out proces starten. InvalidateArrange activeert mogelijk geen metingspas, maar de andere twee wel. Roep deze methoden nooit aan bij het overschrijven van een indelingsmethode, omdat ze vrijwel zeker een indelingslus veroorzaken. Besturingscode hoeft deze doorgaans ook niet aan te roepen. De meeste aspecten van de indeling worden automatisch geactiveerd door wijzigingen in de door het framework gedefinieerde indelingseigenschappen zoals breedte enzovoort te detecteren.
  • LayoutUpdated is een gebeurtenis die wordt geactiveerd wanneer een bepaald aspect van de indeling van het element is gewijzigd. Dit is niet specifiek voor panelen; de gebeurtenis wordt gedefinieerd door FrameworkElement.
  • SizeChanged is een gebeurtenis die alleen wordt geactiveerd nadat de lay-out is voltooid, en geeft aan dat ActualHeight of ActualWidth- als gevolg hiervan zijn gewijzigd. Dit is een andere FrameworkElement gebeurtenis. Er zijn gevallen waarin LayoutUpdated wordt geactiveerd, maar SizeChanged niet. De interne inhoud kan bijvoorbeeld opnieuw worden gerangschikt, maar de grootte van het element is niet gewijzigd.

Verwijzing

Concepten