33

I have a WPF app with multiple controls on each window, some overlayed etc, what i need is a way of getting the app to resize itself automatically depending on the screen resolution.

Any ideas ?

Welsh King
  • 3,178
  • 11
  • 38
  • 60
  • 1
    Why do you need this? If you want to simply resize the window, @Fischermaen gave you the answer. But if you want to change the size of fonts, etc. This is not needed, since WPF already manages this. All WPF rendering is working in virtual coordinates, which are mapped to physical pixels according to system's DPI settings. – Vladimir Perevalov Nov 14 '11 at 13:27
  • Do you want that your window is exactly the size that its content wants? Read this similar [question](http://stackoverflow.com/questions/1746431/wpf-control-size-to-content) then. – dowhilefor Nov 14 '11 at 16:03
  • 1
    but my wpf has cordinates set and font sizes set etc. Basically the software needs to work for different resolutions – Welsh King Nov 18 '11 at 09:09
  • Welsh did you ever find a solutions? @Fischermaens solution doesnt work –  Nov 22 '15 at 01:37
  • How is this different from a maximized window? – Kyle Delaney May 24 '18 at 18:09

4 Answers4

96

The syntax Height="{Binding SystemParameters.PrimaryScreenHeight}" provides the clue but doesn't work as such. SystemParameters.PrimaryScreenHeight is static, hence you shall use:

  <Window x:Class="MyApp.MainWindow"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:tools="clr-namespace:MyApp.Tools"
      Height="{x:Static SystemParameters.PrimaryScreenHeight}" 
      Width="{x:Static SystemParameters.PrimaryScreenWidth}" 
      Title="{Binding Path=DisplayName}"
      WindowStartupLocation="CenterScreen"
      Icon="icon.ico"
  >

And it would fit the whole screen. Yet, you may prefer to fit a percentage of the screen size, e.g. 90%, in which case the syntax must be amended with a converter in a binding spec:

  <Window x:Class="MyApp.MainWindow"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:tools="clr-namespace:MyApp.Tools"
      Height="{Binding Source={x:Static SystemParameters.PrimaryScreenHeight}, Converter={tools:RatioConverter}, ConverterParameter='0.9' }" 
      Width="{Binding Source={x:Static SystemParameters.PrimaryScreenWidth}, Converter={tools:RatioConverter}, ConverterParameter='0.9' }" 
      Title="{Binding Path=DisplayName}"
      WindowStartupLocation="CenterScreen"
      Icon="icon.ico"
  >

Where RatioConverter is here declared in MyApp.Tools namespace as follows:

namespace MyApp.Tools {

    [ValueConversion(typeof(string), typeof(string))]
    public class RatioConverter : MarkupExtension, IValueConverter
    {
      private static RatioConverter _instance;

      public RatioConverter() { }

      public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
      { // do not let the culture default to local to prevent variable outcome re decimal syntax
        double size = System.Convert.ToDouble(value) * System.Convert.ToDouble(parameter,CultureInfo.InvariantCulture);
        return size.ToString( "G0", CultureInfo.InvariantCulture );
      }

      public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
      { // read only converter...
        throw new NotImplementedException();
      }

      public override object ProvideValue(IServiceProvider serviceProvider)
      {
        return _instance ?? (_instance = new RatioConverter());
      }

    }
}

Where the definition of the converter shall inherit from MarkupExtension in order to be used directly in the root element without a former declaration as a resource.

Bernard Hauzeur
  • 2,317
  • 1
  • 18
  • 25
  • how to set this programatically `Height="{Binding Source={x:Static SystemParameters.PrimaryScreenHeight}, Converter={tools:RatioConverter}, ConverterParameter='0.9' }" Width="{Binding Source={x:Static SystemParameters.PrimaryScreenWidth}, Converter={tools:RatioConverter}, ConverterParameter='0.9' }" ` – Vibhesh Kaul Sep 21 '16 at 09:52
  • I agree with phonetagger this is such a good answer, just by making it fit a percentage of the screen size, so that it will ALWAYS fit no matter what the resolution / monitor size... – AndyUK Apr 20 '17 at 09:31
  • 4
    If you do not want the window to cover the task bar, can use MaximizedPrimaryScreenHeight instead of PrimaryScreenHeight. (https://stackoverflow.com/a/35010001) – larsjr May 25 '18 at 07:27
  • Trying to understand... why does your converter need to convert to double and then back to string? Why can't you make it "double-in, double-out"? The parameter `object value` is a boxed object of the same type that you're binding it to, which in this case is `Width` (or `Height`), which are already type `double`. – dotNET May 09 '22 at 05:51
34

Just simply make a binding like that:

<Window x:Class="YourApplication.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="YourApplication" 
    Height="{Binding SystemParameters.PrimaryScreenHeight}" 
    Width="{Binding SystemParameters.PrimaryScreenWidth}">
Fischermaen
  • 12,238
  • 2
  • 39
  • 56
  • will this resize all the controls on the form accordingly ? – Welsh King Nov 18 '11 at 09:14
  • 1
    That depends on how you've designed your form. You can have a fix design or the controls will resize relative to their containers. – Fischermaen Nov 18 '11 at 09:30
  • ooh interesting, I wish id known that when i started, oh well ill give it a test on a blank project and see what happens. So just to clarify, need to make control item widths and heights relative ? I have this , how would i make this resize in line with the window ? – Welsh King Nov 18 '11 at 09:33
  • 2
    @WelshKing: You have to declare your Grid like that ` ` – Fischermaen Nov 18 '11 at 12:33
  • lovely works a treat, now to play around with muliple controls layers :) thank you – Welsh King Nov 18 '11 at 13:40
  • @Fischermaen this solution isn't working for me, do you know why? my buttons are still running off the screen..http://stackoverflow.com/questions/33847852/how-to-resize-c-sharp-wpf-program-to-fit-any-screen-resolution –  Nov 22 '15 at 01:38
  • For fellow developers, this code works for the resolution from 1024x768 to 1920x1080 like a charm [WPF radwindow as a startup object] – Sarathi Jayapal Feb 28 '19 at 04:42
  • 1
    if you have two screen, it uses the primary screen resolution so if the software is in the other screen, it does nothing. – ozkulah Aug 05 '21 at 11:39
1

Based on berhauz's answer. But you can simplify it even further by doing it in code behind(.xaml.cs):

public Window1()
{
    InitializeComponent();
    this.Height = SystemParameters.PrimaryScreenHeight * 0.95;
    this.Width = SystemParameters.PrimaryScreenWidth * 0.95;
}
Zed
  • 11
  • 2
0

Slightly improved version of @berhauz's answer. Uses modern pattern-matching and omits string-to-double-to-string conversion:

[ValueConversion(typeof(double), typeof(double))]
public class RatioConverter : MarkupExtension, IValueConverter
{
  private static RatioConverter _instance;

  public RatioConverter() { }

  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
    if (value == null || parameter is null)
      return null;
    else if (value is double v && parameter is double p)
      return v * p;
    else
      throw new ArgumentException("Both value and parameter must be of type double.");
}

  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  { 
    throw new NotSupportedException();
  }

  public override object ProvideValue(IServiceProvider serviceProvider)
  {
    return _instance ?? (_instance = new RatioConverter());
  }
}

Use it like this:

<Window.Width>
  <Binding Source="{x:Static SystemParameters.PrimaryScreenWidth}" Converter="{local:RatioConverter}">
    <Binding.ConverterParameter>
      <sys:Double>0.9</sys:Double>
    </Binding.ConverterParameter>
  </Binding>
</Window.MaxWidth>
dotNET
  • 33,414
  • 24
  • 162
  • 251