Get the height/width of Window WPF
Asked Answered
K

9

16

I have the following code

<Window x:Class="Netspot.DigitalSignage.Client.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" WindowStyle="SingleBorderWindow" 
        WindowStartupLocation="CenterScreen"
        WindowState="Normal" Closing="Window_Closing">

Any attempt to get the height / width return NaN or 0.0

Can anyone tell me a way of getting it ?

These 2 methods don't work

//Method1
var h = ((System.Windows.Controls.Panel)Application.Current.MainWindow.Content).ActualHeight;
var w = ((System.Windows.Controls.Panel)Application.Current.MainWindow.Content).ActualWidth;

//Method2
double dWidth = -1;
double dHeight = -1;
FrameworkElement pnlClient = this.Content as FrameworkElement;
if (pnlClient != null)
{
     dWidth = pnlClient.ActualWidth;
     dHeight = pnlClient.ActualWidth;
}

The application will not be running full screen.

Kowalski answered 13/6, 2012 at 10:51 Comment(4)
Where are you trying this code ? if you are trying in the Constructor for the Window, it will not work otherwise this.ActualHeight will give you the actual height of the windowPulp
so i have to do it after window_loaded ? good point how can I size a window that yet doesnt exist :)Kowalski
Exactly, you can't get the size of the window if its not loadedPulp
Why are you trying to get the height/width? Maybe there is another way to do whatever you're trying to doLoki
M
15

1.) Subscribe to the window re size event in the code behind:

this.SizeChanged += OnWindowSizeChanged;

2.) Use the SizeChangedEventArgs object 'e' to get the sizes you need:

protected void OnWindowSizeChanged(object sender, SizeChangedEventArgs e)
{
    double newWindowHeight = e.NewSize.Height;
    double newWindowWidth = e.NewSize.Width;
    double prevWindowHeight = e.PreviousSize.Height;
    double prevWindowWidth = e.PreviousSize.Width;
}

Keep in mind this is very general case, you MAY (you may not either) have to do some checking to make sure you have size values of 0.

I used this to resize a list box dynamically as the main window changes. Essentially all I wanted was this control's height to change the same amount the window's height changes so its parent 'panel' looks consistent throughout any window changes.

Here is the code for that, more specific example:

NOTE I have a private instance integer called 'resizeMode' that is set to 0 in the constructor the Window code behind.

Here is the OnWindowSizeChanged event handler:

    protected void OnWindowSizeChanged (object sender, SizeChangedEventArgs e)
    {
        if (e.PreviousSize.Height != 0)
        {
            if (e.HeightChanged)
            {
                double heightChange = e.NewSize.Height - e.PreviousSize.Height;
                if (lbxUninspectedPrints.Height + heightChange > 0)
                {
                    lbxUninspectedPrints.Height = lbxUninspectedPrints.Height + heightChange;
                }
            }
        }
        prevHeight = e.PreviousSize.Height;
    }
Muff answered 4/4, 2014 at 18:30 Comment(1)
This should be the answerFutile
S
11

You can get the width and height that the window was meant to be in the constructor after InitializeComponent has been run, they won't return NaN then, the actual height and width will have to wait until the window has been displayed.

When WindowState == Normal You can do this one from Width / Height after IntializeComponent().

When WindowState == Maximized You could get the screen resolution for this one with

System.Windows.SystemParameters.PrimaryScreenHeight;
System.Windows.SystemParameters.PrimaryScreenWidth;
Sloganeer answered 13/6, 2012 at 11:1 Comment(2)
This is the screen height and width of the primary monitor screen, not necessarily the current screen.Distiller
The question isn't about getting the "current screen" values, it's a question asking why the op is getting NaN instead of a value.Sloganeer
H
5

You have to try to get the ActualWidth/ActualHeight values once the window is Loaded in the UI. Doing it in Window_Loaded works well.

Holocrine answered 13/6, 2012 at 12:40 Comment(0)
T
5

XAML

<Grid x:Name="Grid1">
      <Image x:Name="Back_Image" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>

CS MainWindow() after InitializeComponent();

    Back_Image.Width = Grid1.Width;
    Back_Image.Height = Grid1.Height;
Tjader answered 22/11, 2015 at 6:5 Comment(1)
Welcome to Stack Overflow. When posting an answer please help the poster and future searchers by explaining in your answer how your answer solves their question.Roeder
P
1

WPF does the creation of controls and windows in a deferred manner. So until the window is displayed for the first time, it might not have gone through layouting yet, thus no ActualWidth/ActualHeight. You can wait until the window is loaded and get the properties then, or yet better bind these properties to a target where you need them. You could also force the layouting via UpdateLayout().

Just want to add: try to minimize the amount of size dependant logic, it is almost always possible to avoid it. Unless you are writing a layout panel of course.

Protean answered 13/6, 2012 at 10:58 Comment(0)
C
1

Notice that when you use controls with 100% of with, they have a NaN size till they are being represented

You can check the ActualHeigh or ActualWidth just when the Loaded event is fired, but never try to verify it before the windows controls are created. Forget the idea to control that in the constructor.

In my oppinion, the best place to control this kind of things is The SizeChanged event

Casern answered 18/5, 2016 at 23:18 Comment(0)
M
1

Hi you can get the height of the current screen in WPF with

System.Windows.SystemParameters.PrimaryScreenHeight
Musser answered 10/4, 2022 at 7:36 Comment(0)
D
0

I just add a variable name to my window and then get the width or height of the window i want from its width or height property respectifly.

XAML:

<Window x:Name="exampleName"
   ...
</Window>

C#:

exampleName.Height;

or:

exampleName.Width;
Desma answered 22/7, 2022 at 7:0 Comment(0)
H
0

My solution in case of MVVM...

I have a ViewModelBase, which is the base class for all ViewModel of the app.

1.) I created in the ViewModelBase a virtual method, which could be overriten in the child ViewModels.

public virtual void OnWindowSizeChanged(object sender, SizeChangedEventArgs e) {}

2.) The ctr of the MainWindow : Window class

public MainWindow(object dataContext)
{
    InitializeComponent();

    if (dataContext is ViewModelBase)
    {
        this.SizeChanged += ((ViewModelBase)dataContext).OnWindowSizeChanged;
        DataContext = dataContext;
    }
}

3.) Eg. in the MainViewModel, which is extends the ViewModelBase

public override void OnWindowSizeChanged(object sender, SizeChangedEventArgs e)
{
    Console.WriteLine(e.NewSize.Height);
}
Herzel answered 6/9, 2022 at 11:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.