2010-01-08 47 views
2

我想在父窗口客戶區的右上角放置一個模態對話框(進度窗口)。如何計算WPF中客戶區域的偏移量?

該代碼將把它放在非客戶區域的角落,但是如何計算客戶區域的偏移?

this.Owner=owner; 
this.Left=owner.Left+owner.ActualWidth-Width; 
this.Top=owner.Top; 

編輯:

我發現這個 '解決方案',對正常的Windows的工作原理:

this.Left=owner.Left+owner.ActualWidth-Width-SystemParameters.ResizeFrameVerticalBorderWidth; 
this.Top=owner.Top+SystemParameters.ResizeFrameHorizontalBorderHeight+SystemParameters.WindowCaptionHeight; 

但這會失敗已定製的邊框窗口。

編輯:

的代碼應該不管系統DPI設置(例如的120代替96)的工作。

回答

3

只要你的窗口內容的UIElement的子類(這是正常的情況下),你可以簡單地檢查由內容所覆蓋的區域:

Matrix scaling = PresentationSource.FromVisual(windowContent) 
        .CompositionTarget.TransformFromDevice; 

UIElement windowContent = owner.Content as UIElement; 

Point upperRightRelativeToContent = new Point(
    windowContent.RenderSize.Width + owner.Margin.Right, 
    -owner.Margin.Top); 

Point upperRightRelativeToScreen = 
    windowContent.PointToScreen(upperRightRelativeToContent); 

Point upperRightScaled = 
    scaling.Transform(upperRightRelativeToScreen); 

this.Owner = owner; 
this.Left = upperRightScaled.X - this.Width; 
this.Top = upperRightScaled.Y; 

如果你有,你想有一個奇怪的情況這對於任意Window.Content工作,您必須使用VisualTreeHelper.GetChildCount()和搜索窗口的可視化樹,直到找到ContentPresenterContent屬性匹配Window的屬性,並在上述代碼中將其第一個可視子項用作「windowContent」 。

+0

謝謝,但此代碼似乎只適用於設置爲96 DPI的系統。也許這是一個WPF錯誤,但我需要它來處理120 DPI。 – laktak 2010-01-13 16:41:24

+0

我忘了使用TransformFromDevice來包含縮放。我已將所需的代碼添加到我的答案中,所以現在可以在任何DPI上使用。 – 2010-03-12 05:33:17

+0

很好,謝謝。我只在windowContent有餘量時才發現問題。在這種情況下,您還必須調整((FrameworkElement)windowContent).Margin的upperRightRelativeToContent。 – laktak 2010-03-15 09:45:10