Understanding WPF Layout Panels: Easy Examples of Grid, StackPanel, WrapPanel, DockPanel, Canvas & UniformGrid

If you are just starting out with WPF , layouts are something you must understand very clearly, because they control how every control such as button, textbox, etc. appears on the screen. ⭐ What Are Layout Panels? Think of layout panels like containers or boxes that help you arrange your UI elements . Just like when you pack a suitcase, you organize things in different sections — WPF uses layout panels to organize controls properly. They decide: where controls appear, how they resize, how they adapt when the window grows or shrinks. 📌 Let’s Learn Panels One by One (with real examples) 🟦 1. StackPanel — arrange controls in a line StackPanel arranges items one after another, either top to bottom or left to right. Let me show you a simple example. ✔ Example: Vertical StackPanel <StackPanel Orientation="Vertical">     <Button Content="Save" Width="100"/>     <Button Content="Edit" Width="100"/>     <Button Conte...

How to create Expandable TextBox in Wpf

Step 1: Right click on project 
Step 2: Click on Add and select New Item
Step 3: Search for Custom Control
Step 4: Select Custom Control(WPF)
Step 5: Write ExpandableTextBox in Name and click on Add

It will create one class with the Name ExpandableTextBox with following code:

namespace CustomControl.Controls
{
public class ExpandableTextBox : Control
    {
        static ExpandableTextBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ExpandableTextBox), new FrameworkPropertyMetadata(typeof(ExpandableTextBox)));
        }
    }
}

It will also create a folder called Themes inside this folder it will create ResourceDictionary with the Name Generic with folowing code:

Generic.xaml


<ResourceDictionary
		xmlns:local="clr-namespace:Wpf" 
		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">


    <Style TargetType="{x:Type local:ExpandableTextBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ExpandableTextBox}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                            
                            <!--#region newlly added code -->
                            <Grid x:Name="MainGrid">
                            	<TextBox x:Name="ExpandableTextBox" AcceptsReturn="True"
                                     ScrollViewer.VerticalScrollBarVisibility="Auto"
                            		 ScrollViewer.HorizontalScrollBarVisibility="Auto"/>
                           		<ResizeGrip x:Name="Grip" Cursor="SizeNWSE" HorizontalAlignment="Right" VerticalAlignment="Bottom" Height="14"
                                        Width="14"/>
                        	</Grid>
                            <!--#endregion--> 
                            
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>





Now lets modify the ExpandableTextBox class code

    [TemplatePart(Name = "ExpandableTextBox", Type = typeof(TextBox))]
    [TemplatePart(Name = "Grip", Type = typeof(ResizeGrip))]
    [TemplatePart(Name = "MainGrid", Type = typeof(Grid))]
    public class ExpandableTextBox : Control
    {
        static ExpandableTextBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ExpandableTextBox), new FrameworkPropertyMetadata(typeof(ExpandableTextBox)));
        }
        TextBox _expandableTextbox;
        ResizeGrip _resizeGrip;
        Grid _mainGrid;
        Point LastPoint;
        private bool _dragInProgress;

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            if (this.Template != null)
            {
                _expandableTextbox = this.Template.FindName("ExpandableTextBox", this) as TextBox;
                _resizeGrip = this.Template.FindName("Grip", this) as ResizeGrip;
                _mainGrid = this.Template.FindName("MainGrid", this) as Grid;
                if (_resizeGrip != null)
                    ExpandTextBox();

            }
        }

        private void ExpandTextBox()
        {
            _resizeGrip.MouseDown += (s, e) =>
            {
                LastPoint = Mouse.GetPosition(_resizeGrip);
                _dragInProgress = true;
            };
            Application.Current.MainWindow.MouseUp += (s, e) => _dragInProgress = false;
            Application.Current.MainWindow.MouseMove += (s, e) =>
            {
                if (_dragInProgress)
                {
                    var x = e.GetPosition(_expandableTextbox);
                    var y = _expandableTextbox.VerticalOffset;
                    Point point = Mouse.GetPosition(_resizeGrip);
                    var offset_x = point.X - LastPoint.X;
                    var offset_y = point.Y - LastPoint.Y;
                    var new_width = _expandableTextbox.RenderSize.Width;
                    var new_height = _expandableTextbox.RenderSize.Height;

                    new_width += offset_x;
                    new_height += offset_y;

                    if (new_width > 0 && new_height > 0)
                    {
                        _expandableTextbox.Width = new_width;
                        _expandableTextbox.Height = new_height;

                        var pointToscreen = _expandableTextbox.PointToScreen(x);
                        _expandableTextbox.SetValue(Canvas.LeftProperty, pointToscreen.X);
                        _expandableTextbox.SetValue(Canvas.TopProperty, pointToscreen.Y);

                        _mainGrid.Width = _expandableTextbox.Width;
                        _mainGrid.Height = _expandableTextbox.Height;

                        var translatePoint = _mainGrid.TranslatePoint(x, _mainGrid);
                        _mainGrid.SetValue(Canvas.LeftProperty, translatePoint.X);
                        _mainGrid.SetValue(Canvas.TopProperty, translatePoint.Y);

                        LastPoint = point;

                    }
                }
            };
        }
    }
    
 How to use this control in View?
 
 To use this control first add namespace to your UI like this
 
 xmlns:custom="clr-namespace:CustomControl.Controls"
 
 Now you can show ExpandableTextBox like this
 
 <custom:ExpandableTextBox/>

I hope this code help you. Happy Coding🙂

Comments

Popular posts from this blog

Filter DataGrid and ListView in wpf using ICollectionView

Pagination of DataGrid in WPF using MVVM

How to Create TabControl using Prism Region