1. 获得一个控件相对于另一个控件的位置
//Vector vector = VisualTreeHelper.GetOffset(relativeControl);
//Canvas.SetLeft(this,vector.X);
//Canvas.SetTop(this, vector.Y);
//UIElement.TranslatePoint(new Point(0,0),parentWindow) //Translates a point relative to this element to coordinates that are relative to the specified element.
2. Canvas 的 ClipToBounds="True" 属性, 这个属性比较有用,默认为false,这样会让在canvas显示范围外面的children也能显示出来,这样不太好。
3.MeasureOverride(Size availableSize), 返回希望的size,主要在其中调用 element.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));获得disableSize. ArrangeOverride(Size finalSize) 第一次传入(0,0),第二次传入父节点给其的size.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Markup;
using Pfs.Pam.GUI.Controls;
namespace OverLayDemo
{
public class OverLayout : Canvas
{
protected override Size MeasureOverride(Size availableSize)
{
foreach (UIElement element in Children)
{
element.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
}
if (availableSize.Equals(new Size(Double.PositiveInfinity, Double.PositiveInfinity)))
{
return base.MeasureOverride(availableSize);
}
return availableSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
if (finalSize.Equals(new Size(0, 0)))
return finalSize;
Point leftTop = new Point(0, 0);
Point leftBottom = new Point(0, finalSize.Height);
Point leftMiddle = new Point(0, finalSize.Height / 2);
Point middleTop = new Point(finalSize.Width / 2, 0);
Point middleBottom = new Point(finalSize.Width / 2, finalSize.Height);
Point rightTop = new Point(finalSize.Width, 0);
Point rightMiddle = new Point(finalSize.Width, finalSize.Height / 2);
Point rightBottom = new Point(finalSize.Width, finalSize.Height);
foreach (UIElement element in Children)
{
OverLayPanel panel = element as OverLayPanel;
if (panel == null) //|| panel .IsDrag == true
continue;
if (panel.SlideOutMode == Location.Left)
{
if (panel.VerticalPositionMode == VerticalAlignment.Top)
element.Arrange(new Rect(leftTop, element.DesiredSize));
else if (panel.VerticalPositionMode == VerticalAlignment.Middle)
element.Arrange(new Rect(new Point(0, leftMiddle.Y - element.DesiredSize.Height / 2), element.DesiredSize));
else if (panel.VerticalPositionMode == VerticalAlignment.Bottom)
element.Arrange(new Rect(new Point(0, leftBottom.Y - element.DesiredSize.Height), element.DesiredSize));
else
element.Arrange(new Rect(leftTop, finalSize));
}
else if (panel.SlideOutMode == Location.Rigth)
{
if (panel.VerticalPositionMode == VerticalAlignment.Top)
element.Arrange(new Rect(new Point(rightTop.X - element.DesiredSize.Width, 0), element.DesiredSize));
else if (panel.VerticalPositionMode == VerticalAlignment.Middle)
element.Arrange(new Rect(new Point(rightMiddle.X - element.DesiredSize.Width, rightMiddle.Y - element.DesiredSize.Height / 2), element.DesiredSize));
else if (panel.VerticalPositionMode == VerticalAlignment.Bottom)
element.Arrange(new Rect(new Point(rightBottom.X - element.DesiredSize.Width, rightBottom.Y - element.DesiredSize.Height), element.DesiredSize));
else
element.Arrange(new Rect(leftTop, finalSize));
}
else if (panel.SlideOutMode == Location.Top)
{
if (panel.HorizontalPositionMode == HorizontalAlignment.Left)
element.Arrange(new Rect(leftTop, element.DesiredSize));
else if (panel.HorizontalPositionMode == HorizontalAlignment.Center)
element.Arrange(new Rect(new Point(middleTop.X - element.DesiredSize.Width / 2, 0), element.DesiredSize));
else if (panel.HorizontalPositionMode == HorizontalAlignment.Right)
element.Arrange(new Rect(new Point(rightTop.X - element.DesiredSize.Width, 0), element.DesiredSize));
else
element.Arrange(new Rect(leftTop, finalSize));
}
else if (panel.SlideOutMode == Location.Bottom)
{
if (panel.HorizontalPositionMode == HorizontalAlignment.Left)
element.Arrange(new Rect(new Point(0, leftBottom.Y - element.DesiredSize.Height), element.DesiredSize));
else if (panel.HorizontalPositionMode == HorizontalAlignment.Center)
{
element.Arrange(new Rect(new Point(middleBottom.X - element.DesiredSize.Width / 2, middleBottom.Y - element.DesiredSize.Height), element.DesiredSize));
}
else if (panel.HorizontalPositionMode == HorizontalAlignment.Right)
element.Arrange(new Rect(new Point(rightBottom.X - element.DesiredSize.Width, rightBottom.Y - element.DesiredSize.Height), element.DesiredSize));
else
element.Arrange(new Rect(leftTop, finalSize));
}
}
return finalSize;
}
}
}
改ControlTemplate:
<ControlTemplate>
<Rectangle RadiusX="15" RadiusY="15" Margin="4,4,4,4" SnapsToDevicePixels="True" Fill="LightBlue"/>
<ContentPresenter x:Name="OverlayPanelContent" DockPanel.Dock="Top" />
</ControlTemplate>