Search code examples
c#wpfgridactualwidthactualheight

wpf - measuring the actual width and actual height


I have defined a Grid in XAML like,

<Grid Name="myGrid" Grid.Row="0" Grid.Column="0">
     <!-- row/column definitions are defined in c# file -->
</Grid> 

which is also a part of the other defined grids in xaml file.

In C# file in Constructor, after line InitializeComponent() I have defined grid definitions for rows and columns

public State1() {
    InitializeComponent();
    // define the rows
    for (int i = 0; i < 5; i++) {
       RowDefinition rowDef = new RowDefinition();
       rowDef.Height = new GridLength(1, GridUnitType.Star);
       myGrid.RowDefinitions.Add(rowDef);
    }

    // define the columns
    // column for Line
    ColumnDefinition colDef1 = new ColumnDefinition();
    colDef1.Width = new GridLength(8, GridUnitType.Star);
    myGrid.ColumnDefinitions.Add(colDef1);
    // column for TextBlock
    ColumnDefinition colDef2 = new ColumnDefinition();
    colDef2.Width = new GridLength(1, GridUnitType.Star);
    myGrid.ColumnDefinitions.Add(colDef2);

    for (int i = 0; i < 5; i++) {
        // draw dashed line
        Line line= new Line() {
            X2 = myGrid.ColumnDefinitions[0].ActualWidth, // actual width is 0
            Stroke = Brushes.Black, 
            StrokeDashArray = {10, 10, 10, 10},
            StrokeThickness = 1
        };
        Grid.SetRow(line, i);
        Grid.SetColumn(line, 0);
        myGrid.Children.Add(line);
        // draw text
        Viewbox vb_txtBlock = new Viewbox();
        TextBlock txtBlock = new TextBlock();
        txtBlock.Text = "Line " + (i+1);
        vb_txtBlock.Child = txtBlock;
        Grid.SetRow(vb_txtBlock, i);
        Grid.SetColumn(vb_txtBlock, 1);
        myGrid.Children.Add(vb_txtBlock);
    }
}

So, my problem is myGrid.ColumnDefinitions[0].ActualWidth returns 0 value. I've read around other questions and problems, and I have found out that that ActualHeight and ActualWidth are not set until the control is measured and arranged.

My questions is, where in my c# code I could measure the actual width and height, so that I can use the Actual Width and Height ?


Solution

  • You should put the initialization code after InitializeComponent and getting the measurements in the Loaded event like this:

        public Window2()
        {
            InitializeComponent();
            for (int i = 0; i < 5; i++)
            {
                RowDefinition rowDef = new RowDefinition();
                rowDef.Height = new GridLength(1, GridUnitType.Star);
                myGrid.RowDefinitions.Add(rowDef);
            }
    
            // define the columns
            // column for Line
            ColumnDefinition colDef1 = new ColumnDefinition();
            colDef1.Width = new GridLength(8, GridUnitType.Star);
            myGrid.ColumnDefinitions.Add(colDef1);
            // column for TextBlock
            ColumnDefinition colDef2 = new ColumnDefinition();
            colDef2.Width = new GridLength(1, GridUnitType.Star);
            myGrid.ColumnDefinitions.Add(colDef2);
        }
    
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            for (int i = 0; i < 5; i++)
            {
                // draw dashed line
                Line line = new Line()
                {
                    X2 = myGrid.ColumnDefinitions[0].ActualWidth, // actual width is 0
                    Stroke = Brushes.Black,
                    StrokeDashArray = { 10, 10, 10, 10 },
                    StrokeThickness = 1
                };
                Grid.SetRow(line, i);
                Grid.SetColumn(line, 0);
                myGrid.Children.Add(line);
                // draw text
                Viewbox vb_txtBlock = new Viewbox();
                TextBlock txtBlock = new TextBlock();
                txtBlock.Text = "Line " + (i + 1);
                vb_txtBlock.Child = txtBlock;
                Grid.SetRow(vb_txtBlock, i);
                Grid.SetColumn(vb_txtBlock, 1);
                myGrid.Children.Add(vb_txtBlock);
            }
        }
    

    I get a valid ActualWidth when debugging.