2010-01-08 65 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