0

i stumbled across a curiosity in WPF which i couldn't explain myself an which i couldn't solve by searching online. So i hope one of you is able to give me a hint to understand my mistake.

Problem: The wpf-window dimensions seems to be 16 units bigger than the screen-resolution. The 16 pixels/units are independent from dimension (windowwidth, windowheight) and screen resolution. The Problem is shown in the following Application:

XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="250" Width="350">
    <DockPanel Margin="10,10,0,0">
        <DockPanel Width="152" DockPanel.Dock="Top" VerticalAlignment="Top" HorizontalAlignment="Left">
            <TextBlock x:Name="displayHeight" HorizontalAlignment="Left" Margin="0,5,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="60"/>
            <Label Content="Displayheight" HorizontalAlignment="Left" VerticalAlignment="Top" Height="30"/>

        </DockPanel>

        <DockPanel Width="148" DockPanel.Dock="Top" VerticalAlignment="Top" HorizontalAlignment="Left">
            <TextBlock x:Name="displayWidth" HorizontalAlignment="Left" Margin="0,5,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="60"/>
            <Label Content="Displaywidth" HorizontalAlignment="Left" VerticalAlignment="Top" Height="30"/>

        </DockPanel>
        <DockPanel Width="162" DockPanel.Dock="Top" VerticalAlignment="Top" HorizontalAlignment="Left">
            <TextBlock HorizontalAlignment="Left" Margin="0,5,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Text="{Binding ActualHeight, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" Width="60"/>
            <Label Content="Windowheight" HorizontalAlignment="Left" VerticalAlignment="Top" Height="30" Width="92"/>

        </DockPanel>
        <DockPanel Width="153" DockPanel.Dock="Top" VerticalAlignment="Top" HorizontalAlignment="Left">
            <TextBlock HorizontalAlignment="Left" Margin="0,5,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Text="{Binding ActualWidth, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" Width="60"/>
            <Label Content="Windowwidth" HorizontalAlignment="Left" VerticalAlignment="Top" Height="30"/>

        </DockPanel>

    </DockPanel>
</Window>

C#:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Forms;
using System.Drawing;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            IntPtr ownerHandle = Process.GetCurrentProcess().MainWindowHandle;
            WpfScreen currentScreen = WpfScreen.GetScreenFrom(ownerHandle);
            Rect workingArea = currentScreen.WorkingArea;

            this.displayHeight.Text = workingArea.Height.ToString();
            this.displayWidth.Text = workingArea.Width.ToString();
        }
    }

    public class WpfScreen
    {
        public static WpfScreen GetScreenFrom(IntPtr windowIntPTR)
        {
            Screen screen = System.Windows.Forms.Screen.FromHandle(windowIntPTR);
            WpfScreen wpfScreen = new WpfScreen(screen);
            return wpfScreen;
        }

        private readonly Screen screen;

        internal WpfScreen(System.Windows.Forms.Screen screen)
        {
            this.screen = screen;
        }

        public Rect WorkingArea
        {
            get { return this.GetRect(this.screen.WorkingArea); }
        }

        private Rect GetRect(Rectangle value)
        {
            return new Rect
            {
                X = value.X,
                Y = value.Y,
                Width = value.Width,
                Height = value.Height
            };
        }
    }
}

Basically the code is needed to set the max-Values for Height/Width of an Excel-Addin to the available working area of the display. The above application is just a very simple example to illustrate the problem.

For me it would be ok to just know that the 16 pixels are universally valid and independent from hard-/software. Nevertheless it would be great to get an Explanation whats the reason for this behaviour.

Greetings and THX in advance,

Sven

Sven.L
  • 45
  • 1
  • 9

1 Answers1

0

Why not use

WPF WindowState="Maximized"

see: How can I make a WPF window maximized on the screen with the mouse cursor?

incureforce
  • 21
  • 1
  • 3
  • The default should be SizeToContent because the average wpf-Window is definitely smaller than the screen workingarea. One big Problem is the use of a projector, which might only have a 640x480 resolution. – Sven.L May 29 '17 at 14:18
  • Oh sorry, maybe this one 'll help you: https://msdn.microsoft.com/en-us/library/system.windows.systemparameters(v=vs.110).aspx (e.g. BorderWidth) – incureforce May 29 '17 at 14:21
  • No worries. I should have made this clear: Default WPF-Size should be SizeToContent, Min = 640*480 and Max = workingarea. I just took a look into the Systemparameters but unfortunately i didn't found the right value. BorderWidth is 5.0 in my case (and i didn't know exactly what it stands for...) – Sven.L May 29 '17 at 14:32
  • Now I got you, the BorderWidth is the Width between the ClientArea from the Window and the Window itself. CaptionTitle is the Height of the Title Bar (and don't add BorderWidth to it ^^). With those values and your WPFScreen class you are able to calculate the maximum size for the clientarea of your current Screen (for your window). If you check for Window move / redraw events you can re-check the current Screen and tweak the max values. – incureforce May 29 '17 at 14:55
  • Thanks for your effort at first! I'm not sure if this solves my problem but i will dig a bit deeper into the SystemParameters tomorrow and reply here... – Sven.L May 29 '17 at 15:07