请查看附件图片。我通过RenderTransformOrigin =“0.5,0.5”将文本块原点设置为它的中心。现在我想基于参考点移动文本块。可能是(0,0)或(10,10)或......这些是绝对点。例如,在(0,0)的情况下,文本块应基于其参考点移动到绝对值(0,0)。我知道如何通过TranslateTransform相对移动,但是这种情况我需要绝对变换。
答案 0 :(得分:1)
文本块应移至绝对值(0,0)
我认为“绝对”是指“相对于MainWindow”。我不认为有一个内置的渲染变换到相对于另一个元素的坐标。但是,你总是可以使用X
和Y
的绑定 - 我想它必须是一个MultiBinding,允许你将a)MainWindow,b)TextBlock转换为“亲属” “偏移对应于MainWindow中的绝对坐标。
XAML应该是这样的(例如,X坐标只在这里)。您可以在ConverterParameter
:
<TextBlock Text="TextBlock" RenderTransformOrigin="0.5,0.5">
<TextBlock.RenderTransform>
<TranslateTransform>
<TranslateTransform.X>
<MultiBinding>
<MultiBinding.ConverterParameter>
<Point X="10" Y="10" />
</MultiBinding.ConverterParameter>
<MultiBinding.Converter>
<converters:TranslateConverter />
</MultiBinding.Converter>
<Binding RelativeSource="{RelativeSource AncestorType=Window}" />
<Binding RelativeSource="{RelativeSource AncestorType=TextBlock}" />
</MultiBinding>
</TranslateTransform.X>
</TranslateTransform>
</TextBlock.RenderTransform>
</TextBlock>
“TranslateConverter”是将引用(窗口)和目标(TextBlock)转换为相对偏移量的位置。使用TransformToVisual
将TextBlock的坐标转换为Window的坐标。
public class TranslateConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var window = values[0] as Window;
var textblock = values[1] as TextBlock;
Point absolutePoint = (parameter as Point?) ?? new Point(0, 0);
// convert the target point from the Window's coordinates to the TextBlock's coordinates
var generalTransform = window.TransformToVisual(textblock);
Point offset = generalTransform.Transform(absolutePoint);
// get the position of the RenderTransform origin in the TextBlock's coordinates
Point relativePoint = textblock.RenderTransformOrigin;
double reference = relativePoint.X * textblock.ActualWidth;
// the relative offset of the 2 values above will move the TextBlock's origin to an "absolute" position
return offset.X - reference;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
上面只对X进行了变换,但你可以通过为每个坐标使用一个单独的转换器类来扩展它以同时执行X和Y.
关于上述内容的一个注意事项:转换只会在加载时运行一次。如果TextBlock正在移动,并且您需要连续执行转换,那么您可能必须具有创造性。 :)
答案 1 :(得分:1)
也许你需要这个
void MoveToPoint(UIElement sender, Point point)
{
Canvas.SetLeft(sender, point.X - sender.RenderTransformOrigin.X * sender.ActualWidth);
Canvas.SetTop(sender, point.Y - sender.RenderTransformOrigin.Y * sender.ActualHeight);
}
到Xaml(patern MVVM): 你需要写转换器和属性Canvas.Left和Canvas.Top使用Binding。它的代码比以前多。
示例转换器(示例6)http://www.codeproject.com/Articles/29054/WPF-Data-Binding-Part
在转换器中需要发送2个参数sender.RenderTransformOrigin.X和ActualWidth。
使用某些参数观察转换器(俄语) - http://habrahabr.ru/post/141107/