2013-12-16 76 views
0

在我们的拖拽实现中,我们喜欢装饰者应用装饰元素的变形值。wpf在绘制拖拽装饰时应用变换

所述变换可应用于UI元素在XAML这样的:

<DockPanel.LayoutTransform> 
    <TransformGroup> 
     <ScaleTransform ScaleX="0.75" ScaleY="0.75"/> 
     <RotateTransform Angle="10" /> 
    </TransformGroup> 
</DockPanel.LayoutTransform> 
    <TextBlock> 
     <TextBlock.LayoutTransform> 
... 

这是变换是如何被总结祖先元素的所施加的变换检索到:

public static Transform GetAncestorTransforms(this DependencyObject descendant) 
    { 
     TransformGroup transformGroup = new TransformGroup(); 
     DependencyObject dObj = descendant; 
     do 
     { 
      Visual visual = dObj as Visual; 
      if (visual != null) 
      { 
       // determine the current transform by matrix determinants 
       Transform t = VisualTreeHelper.GetTransform(visual); 
       if (t != null) 
       { 
        transformGroup.Children.Add(t); 
       } 
      } 
      dObj = VisualTreeHelper.GetParent(dObj); 
     } 
     while (dObj != null); 

     return transformGroup; 
    } 

装饰器绘制一个圆矩形在UIElement周围

protected override void OnRender(DrawingContext drawingContext) 
    { 
     var transform = (AdornedItem as DependencyObject).GetAncestorTransforms(); 
     if (transform != null) 
     { 
      drawingContext.PushTransform(transform); 
     } 
     Rect rect = new Rect(AdornedItem.TranslatePoint(new Point(0, 0), AdornedElement), AdornedItem.RenderSize); 
     drawingContext.DrawRoundedRectangle(null, new Pen(Foreground, 2), rect, 2, 2); 
     if (transform != null) 
     { 
      drawingContext.Pop(); 
     } 
    } 

该代码绘制了广告orner以正确的大小(例如如果它是一个缩放变换),或者它将装饰者旋转到正确的角度(如果存在倾斜/旋转变形),但无论如何,该矩形永远不会围绕所装饰的元素。它在它旁边。这看起来像一个抵消问题? (请注意,问题已经出现,只有在wohole可视化树中进行单个变换时,当有更多变换时,我知道我可能会在GetAncestorTransforms()中交换总结变换的顺序)。

回答

0

找到的解决方案: 上面的代码工作,除了一件事: AdornedItem.TranslatePoint()通过(已经)转换的UIElements计算周围矩形的起点。为了不应用两次转换,请从点删除它。

Point pos = AdornedItem.TranslatePoint(new Point(0, 0), AdornedElement); 
if (transform != null) 
{ 
    pos = transform.Inverse.Transform(pos); 
} 
Rect rect = new Rect(pos, AdornedItem.RenderSize);