PageSourceSearch

https://docs.avaloniaui.net/assets/js/c981923c.d1b4b21d.js

js avaloniaui.net collected 2026-09-24 17:16:02 UTC 10,288 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkavalonia_docs=self.webpackChunkavalonia_docs||[]).push([[185],{99774:(e,n,l)=>{l.r(n),l.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"layout/panels/panel","title":"Panel","description":"A basic layout control that overlays multiple child controls on top of each other, positioning them with alignment properties.","source":"@site/controls/layout/panels/panel.md","sourceDirName":"layout/panels","slug":"/layout/panels/panel","permalink":"/controls/layout/panels/panel","draft":false,"unlisted":false,"editUrl":"https://github.com/AvaloniaUI/avalonia-docs/tree/main/controls/layout/panels/panel.md","tags":[],"version":"current","lastUpdatedBy":"Luke","lastUpdatedAt":1776689157000,"frontMatter":{"id":"panel","title":"Panel","description":"A basic layout control that overlays multiple child controls on top of each other, positioning them with alignment properties.","doc-type":"reference"},"sidebar":"documentationSidebar","previous":{"title":"GridSplitter","permalink":"/controls/layout/panels/gridsplitter"},"next":{"title":"RelativePanel","permalink":"/controls/layout/panels/relativepanel"}}');var t=l(74848),o=l(28453);const a={id:"panel",title:"Panel",description:"A basic layout control that overlays multiple child controls on top of each other, positioning them with alignment properties.","doc-type":"reference"},i="Panel",s={},c=[{value:"Common properties",id:"common-properties",level:2},{value:"Basic example",id:"basic-example",level:2},{value:"Controlling overlap with <code>ZIndex</code>",id:"controlling-overlap-with-zindex",level:2},{value:"Setting a background for hit testing",id:"setting-a-background-for-hit-testing",level:2},{value:"Using <code>Panel</code> as a base for custom panels",id:"using-panel-as-a-base-for-custom-panels",level:2},{value:"Other panel controls",id:"other-panel-controls",level:2},{value:"See also",id:"see-also",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components},{XamlPreview:l}=n;return l||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("XamlPreview",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"panel",children:"Panel"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"Panel"})," is the most basic layout control that can contain multiple child controls. It draws children in the order they appear in your XAML, layering them on top of each other. Each child is positioned according to its ",(0,t.jsx)(n.code,{children:"HorizontalAlignment"})," and ",(0,t.jsx)(n.code,{children:"VerticalAlignment"})," properties."]}),"\n",(0,t.jsxs)(n.p,{children:["Because ",(0,t.jsx)(n.code,{children:"Panel"})," does not arrange children into rows, columns, or any other structure, it is best suited for scenarios where you need overlapping content, such as placing text over an image or stacking decorative elements."]}),"\n",(0,t.jsx)(n.h2,{id:"common-properties",children:"Common properties"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Property"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"Backgroun
1d"})}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"IBrush"})}),(0,t.jsxs)(n.td,{children:["The background brush for the panel. You must set this (even to ",(0,t.jsx)(n.code,{children:"Transparent"}),") for the panel to receive pointer events."]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"Children"})}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"Controls"})}),(0,t.jsx)(n.td,{children:"The collection of child controls contained in the panel."})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"basic-example",children:"Basic example"}),"\n",(0,t.jsx)(n.p,{children:"This example uses some 50% opacities to demonstrate that child controls overlap."}),"\n",(0,t.jsx)(l,{children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-xml",children:'<Panel xmlns="https://github.com/avaloniaui"\n       Margin="10">\n    <Rectangle Fill="Red" Height="100" VerticalAlignment="Top"/>\n    <Rectangle Fill="Green" Height="100" VerticalAlignment="Bottom"/>\n    <Rectangle Fill="Blue" Width="100" HorizontalAlignment="Right" />\n    <Rectangle Fill="Orange" Width="100" HorizontalAlignment="Left"/>\n</Panel>\n'})})}),"\n",(0,t.jsxs)(n.h2,{id:"controlling-overlap-with-zindex",children:["Controlling overlap with ",(0,t.jsx)(n.code,{children:"ZIndex"})]}),"\n",(0,t.jsxs)(n.p,{children:["When children overlap, you can control the draw order with the ",(0,t.jsx)(n.code,{children:"ZIndex"})," attached property. Higher values draw on top of lower values. By default, all children have a ",(0,t.jsx)(n.code,{children:"ZIndex"})," of 0 and are drawn in the order they appear in markup."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-xml",children:'<Panel>\n    <Border Background="Red" Width="100" Height="100" ZIndex="1" />\n    <Border Background="Blue" Width="100" Height="100" Margin="30,30,0,0" ZIndex="2" />\n</Panel>\n'})}),"\n",(0,t.jsxs)(n.p,{children:["In this example, the blue border renders on top of the red border because it has a higher ",(0,t.jsx)(n.code,{children:"ZIndex"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"setting-a-background-for-hit-testing",children:"Setting a background for hit testing"}),"\n",(0,t.jsxs)(n.p,{children:["If you leave ",(0,t.jsx)(n.code,{children:"Backgroun
1d"})," unset, the panel is transparent to pointer events. Clicks and other pointer interactions pass through to whatever is behind the panel. To make the panel respond to pointer events across its entire area, set ",(0,t.jsx)(n.code,{children:"Background"})," to ",(0,t.jsx)(n.code,{children:"Transparent"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-xml",children:'<Panel Background="Transparent">\n    <TextBlock Text="This panel captures pointer events everywhere." />\n</Panel>\n'})}),"\n",(0,t.jsxs)(n.h2,{id:"using-panel-as-a-base-for-custom-panels",children:["Using ",(0,t.jsx)(n.code,{children:"Panel"})," as a base for custom panels"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Panel"})," serves as the base class for all built-in panel controls. If none of the built-in panels meet your layout requirements, you can create a custom panel by deriving from ",(0,t.jsx)(n.code,{children:"Panel"})," and overriding its ",(0,t.jsx)(n.code,{children:"MeasureOverride"})," and ",(0,t.jsx)(n.code,{children:"ArrangeOverride"})," methods."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-csharp",children:"public class MyCustomPanel : Panel\n{\n    protected override Size MeasureOverride(Size availableSize)\n    {\n        foreach (var child in Children)\n        {\n            child.Measure(availableSize);\n        }\n\n        return availableSize;\n    }\n\n    protected override Size ArrangeOverride(Size finalSize)\n    {\n        foreach (var child in Children)\n        {\n            child.Arrange(new Rect(finalSize));\n        }\n\n        return finalSize;\n    }\n}\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsxs)(n.p,{children:["For a complete walkthrough, see ",(0,t.jsx)(n.a,{href:"/docs/custom-controls/custom-panel",children:"Custom panel"}),"."]})}),"\n",(0,t.jsx)(n.h2,{id:"other-panel-controls",children:"Other panel controls"}),"\n",(0,t.jsx)(n.p,{children:"If you need more control over how child elements are positioned, consider one of these specialized panels:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/controls/layout/panels/stackpanel",children:"Stack panel"}),": arranges children in a single horizontal or vertical line."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/controls/layout/panels/dockpanel",children:"Dock panel"}),": docks children to the edges of the panel."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/controls/layout/panels/grid",children:"Grid"}),": arranges children in rows and columns."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/controls/layout/panels/wrappanel",children:"Wrap panel"}),": arranges children in a line that wraps when it reaches the panel edge."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/controls/layout/panels/canvas",children:"Canvas"}),": positions children at explicit coordinates."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/controls/layout/panels/relativepanel",children:"Relative panel"}),": positions children relative to each other or to the panel itself."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/controls/layout/panels/uniformgrid",children:"Uniform grid"}),": arranges children in a grid with equally sized cells."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"see-also",children:"See also"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/api/avalonia/controls/panel",children:"Panel API reference"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsxs)(n.a,{href:"https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.Controls/Panel.cs",children:[(0,t.jsx)(n.code,{children:"Panel.cs"})," source code on GitHub"]})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/docs/custom-controls/custom-panel",children:"Custom panel"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,l)=>{l.d(n,{R:()=>a,x:()=>i});var r=l(96540);const t={},o=r.createContext(t);function a(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.