4

I just wrote a small program in C# that displays quotations on my desktop. My problem is to center the window of the application. To calculate the wanted location of the window i'm using this formula:

        Left = (Screen.PrimaryScreen.Bounds.Width - this.ActualWidth) / 2;
        Top = (Screen.PrimaryScreen.Bounds.Height - this.ActualHeight) / 2;

Unfortunately this.ActualWidth and this.ActualHeight give wrong values as you can see in the screenshot. 188,4 and 189 instead of 1000(+).

http://www.directupload.net/file/d/4044/4x2tgadg_png.htm

Here is the GUI:

http://www.directupload.net/file/d/4044/63rx2sul_png.htm

The code in text form:

public partial class QuotePresenter : Window
{
    public QuotePresenter()
    {
        InitializeComponent();
        setSize();
    }

    private void setSize()
    {
        MaxWidth = Screen.PrimaryScreen.Bounds.Width * 0.8;
        MaxHeight = Screen.PrimaryScreen.Bounds.Height * 0.8;
    }

    private void setLocation()
    {
        Left = (Screen.PrimaryScreen.Bounds.Width - this.ActualWidth) / 2;
        Top = (Screen.PrimaryScreen.Bounds.Height - this.ActualHeight) / 2;

        System.Windows.MessageBox.Show("Actual Width: " + this.ActualWidth + "\nWidth: " + this.Width);
    }

    public void SetQuote(Quotation quote)
    {
        Dispatcher.Invoke(new Action(() =>
        {
            tb_content.Text = quote.Content;
            tb_author.Text = "- " + quote.Author;

            setLocation();
        }));
    }
}

Can somebody tell me what went wrong here?

Thanks in advance!

6
  • I copied this code, removing all the custom classes, but was not able to duplicate your results. Commented Jul 10, 2015 at 16:25
  • The "SetQuote" function is called from another thread - could that somehow cause this errors? Commented Jul 10, 2015 at 16:38
  • When I put the "setLocation" outside of the Dispatcher.Invoke I get an "InvalidOperationException" - The calling thread cannot access this object because a different thread owns it. at this line of code: Left = (Screen.PrimaryScreen.Bounds.Width - this.ActualWidth) / 2; Commented Jul 10, 2015 at 16:41
  • No, the Dispatcher.Invoke() method invokes the dispatcher thread, so it's being called on the UI thread. Commented Jul 10, 2015 at 16:42
  • I have two GUI's a MainWindow with settings and stuff and the QuotePresenter. The MainWindow creates a thread "presentQuotes" and this thread calls the QuotePresenter.setQuote(...) so I actually have 3 threads but that probably doesn't make any difference ^^ Commented Jul 10, 2015 at 16:48

1 Answer 1

6

I see two issues with your code. First of all, you're attempting to grab the new width of the window before it has resized itself to accommodate the updated text. In other words, you're getting the old width (before you inserted the quote) instead of the new width. To force the window to resize itself immediately, call UpdateLayout() prior to your setLocation() method.

The second problem is that you've got a potential unit mismatch. WPF window sizes are specified in layout units equal to 1/96th of an inch (which may or may not be a pixel, depending on your DPI settings). But the desktop screen resolution is being queried in pixels. So depending on your user's display settings you might be mixing units and ending up with an incorrect location for your window.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.