Problems with binding to Window Height and Width

38,518

Solution 1

I will try to answer my own question. The bindings are working, but we can't really be sure that the layout system asks for e.g. the Width property of the window.

From MSDN:

If this element is a child element within some other element, then setting this property to a value is really only a suggested value. The layout system as well as the particular layout logic of the parent element will use the value as a nonbinding input during the layout process. In practical terms, a FrameworkElement is almost always the child element of something else; even when you set the Height on Window. (For Window, that value is used when the underlying application model establishes the basic rendering assumptions that create the Hwnd that hosts the application.)

A solution that seems to work is to bind the WindowWidth property to MinWidth and MaxWidth, as well as Width. One of these will be retrieved, at least in the test scenario I was using above.

Solution 2

Try using two way binding, it worked for me:

Width="{Binding Path=xExt, Mode=TwoWay}"

Solution 3

I had the same problem and I noticed that it depends whether height or width is written first in xaml. If height is first, then Binding work only for it and vice versa. The solution was to set Binding mode to 'TwoWay': The project I have made was with MS Studio 2010 and .NET 4.0

Solution 4

OK,

I had the same problem and could not bind correctly the window dimensions (min, max, normal) to my viewmodel through XAML.

I don't know why but you can acheive all those bindings without any problem if you do them by code instead of by XAML.

Here is my C# code that worked :

this.SetBinding(Window.WidthProperty, new Binding("Width") { Source = MyViewModel, Mode=BindingMode.TwoWay });
this.SetBinding(Window.HeightProperty, new Binding("Height") { Source = MyViewModel, Mode=BindingMode.TwoWay });
this.SetBinding(Window.MaxWidthProperty, new Binding("MaxWidth") { Source = MyViewModel });
this.SetBinding(Window.MaxHeightProperty, new Binding("MaxHeight") { Source = MyViewModel });
this.SetBinding(Window.MinWidthProperty, new Binding("MinWidth") { Source = MyViewModel });
this.SetBinding(Window.MinHeightProperty, new Binding("MinHeight") { Source = MyViewModel });

It is strange that it only works in code and not in XAML. It is even more strange that it binds TwoWay by default for mMin and Max dimensions but not for Normal dimensions for which you have to specify « Mode=BindingMode.TwoWay ».

There should be a bug that Microsoft has to correct about this...

Solution 5

Additionally you can use SizeToContent="WidthAndHeight" with the MinHeight and MinWidth, so not extra call would require for the MaxHeight and MaxWidth.

Share:
38,518

Related videos on Youtube

D.H.
Author by

D.H.

Updated on July 09, 2022

Comments

  • D.H.
    D.H. almost 2 years

    I have some problems when I try to bind the height and width of a window to properties in my view model. Here is a small sample app to illustrate the problem. This is the code in app.xaml.xs

    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
           base.OnStartup(e);
            MainWindow mainWindow = new MainWindow();
            MainWindowViewModel mainWindowViewModel = new MainWindowViewModel();
            mainWindow.DataContext = mainWindowViewModel;
            mainWindow.Show();
        }
    }
    

    This is MainWindow.xaml:

    <Window x:Class="TestApp.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Height="{Binding WindowHeight}" 
            Width="{Binding WindowWidth}"
            BorderThickness="{Binding WindowBorderThickness}">
    </Window>
    

    And this is the view model:

    public class MainWindowViewModel
    {
        public int WindowWidth { get { return 100; } }
        public int WindowHeight { get { return 200; } }
        public int WindowBorderThickness { get { return 8; } }
    }
    

    When the program is started the getters of WindowHeight and WindowBorderThickness (but not WindowWidth) are called, so the height and the border of the window is set properly, but not the width.

    I then add button that will trigger PropertyChanged for all properties, so that the view model now looks like this:

    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        public void TriggerPropertyChanges()
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("WindowWidth"));
                PropertyChanged(this, new PropertyChangedEventArgs("WindowHeight"));
                PropertyChanged(this, new PropertyChangedEventArgs("WindowBorderThickness"));
            }
    
        }
    
        public ICommand ButtonCommand { get { return new RelayCommand(delegate { TriggerPropertyChanges(); }); } }
    
        public int WindowWidth { get { return 100; } }
        public int WindowHeight { get { return 200; } }
        public int WindowBorderThickness { get { return 8; } }
    }
    

    Now, when I click the button, the getter of WindowBorderThickness is called, but not the ones for WindowWidth and WindowHeight. It all just seems very weird and inconsistent to me. What am I missing?

    • paranoidduck
      paranoidduck about 14 years
      do you have any warning in the Output Window while debugging?
  • D.H.
    D.H. about 14 years
    The basic difference here is that you are binding to the MainWindow itself while I am binding to a separate view model. This seems to make a difference, for some reason. If I implement your sliders against my view model, it won't work (unless I also bind to MinHeight and MaxHeight like I stated in my own answer). Thanks for the example anyway.
  • Martin Schneider
    Martin Schneider about 6 years
    same here. Did not work in XAML, but in code. Binding to Width and Height was enough in my case.