1
votes

I'm trying to make my main window to remember and restore the position and size on startup. So I tried to bind my window's startup location to a properties in my viewmodel as following:

<Window x:Class="MyApp.Views.MainWindow"
    ...
    Width="{Binding Width}"
    Height="{Binding Height}"
    WindowStartupLocation="{Binding WindowStartupLocation}"
    WindowState="{Binding WindowState}"
    MinHeight="600"
    MinWidth="800"
    Closing="OnWindowClosing"
    Closed="OnWindowClosed"
    ContentRendered="OnMainWindowReady"
    ...>

My viewmodel:

        ...

        // Default settings
        WindowState = (WindowState)FormWindowState.Normal;
        this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
        Width = 800;
        Height = 600;

        // check if the saved bounds are nonzero and is visible on any screen
        if (Properties.Settings.Default.WindowStartupLocation != Rectangle.Empty &&
            IsVisibleOnAnyScreen(Properties.Settings.Default.WindowStartupLocation))
        {
            this.WindowStartupLocation = WindowStartupLocation.Manual;
            this.WindowState = (WindowState)Properties.Settings.Default.WindowState;
            Height = Properties.Settings.Default.WindowStartupLocation.Size.Height;
            Width = Properties.Settings.Default.WindowStartupLocation.Size.Width;
            Left = Properties.Settings.Default.WindowStartupLocation.Left;
            Top = Properties.Settings.Default.WindowStartupLocation.Top;
        }
        ...

When i run the application i get a System.Windows.Markup.XamlParseException and Additional information: A 'Binding' cannot be set on the 'WindowStartupLocation' property of type 'MainWindow'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.

How should i correct this?

2

2 Answers

7
votes

Try using attached behavior which lets you bind the WindowStartupLocation property:

namespace YourProject.PropertiesExtension
{
    public static class WindowExt
    {
        public static readonly DependencyProperty WindowStartupLocationProperty;

        public static void SetWindowStartupLocation(DependencyObject DepObject, WindowStartupLocation value)
        {
            DepObject.SetValue(WindowStartupLocationProperty, value);
        }

        public static WindowStartupLocation GetWindowStartupLocation(DependencyObject DepObject)
        {
            return (WindowStartupLocation)DepObject.GetValue(WindowStartupLocationProperty);
        }

        static WindowExt() 
        {            
            WindowStartupLocationProperty = DependencyProperty.RegisterAttached("WindowStartupLocation",
                                                      typeof(WindowStartupLocation),
                                                      typeof(WindowExt),
                                                      new UIPropertyMetadata(WindowStartupLocation.Manual, OnWindowStartupLocationChanged));
        }

        private static void OnWindowStartupLocationChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            Window window = sender as Window; 

            if (window != null) 
            {
                window.WindowStartupLocation = GetWindowStartupLocation(window);
            }
        }
    }
}

The usage:

<Window
  PropertiesExtension:WindowExt.WindowStartupLocation="{Binding ..}" />

As the error stated, WindowStartupLocation is not a dependency propety, which means you can't bind it. The solution can be either deriving from Window, and creating dependency property, or using attached behavior.

-2
votes

You cannot bind the WindowsStartupLocation, this line generates the error:

WindowStartupLocation="{Binding WindowStartupLocation}"

You can set it to some particular value, like that:

WindowStartupLocation="CenterScreen"