基于参考点的WPF文本块翻译

基于参考点的WPF文本块翻译,wpf,wpf-controls,textblock,Wpf,Wpf Controls,Textblock,请检查所附图片。我通过renderTransferorMorigin=“0.5,0.5”将文本块原点设置为其中心。现在我想基于参考点移动textblock。可以是(0,0)或(10,10)或。。。。。。这些是绝对点。例如,在(0,0)的情况下,textblock应基于其参考点移动到绝对(0,0)。我知道如何通过TranslateTransform相对移动,但在这种情况下,我需要绝对变换 文本块应移到绝对值(0,0) 我假设“绝对”是指“相对于主窗口”。我不认为有一个内置的渲染转换到相对于另一个

请检查所附图片。我通过renderTransferorMorigin=“0.5,0.5”将文本块原点设置为其中心。现在我想基于参考点移动textblock。可以是(0,0)或(10,10)或。。。。。。这些是绝对点。例如,在(0,0)的情况下,textblock应基于其参考点移动到绝对(0,0)。我知道如何通过TranslateTransform相对移动,但在这种情况下,我需要绝对变换

文本块应移到绝对值(0,0)

我假设“绝对”是指“相对于主窗口”。我不认为有一个内置的渲染转换到相对于另一个元素的坐标。但是,您可以始终为
X
Y
使用绑定——我想它必须是一个多绑定,才能允许您将a)主窗口b)文本块转换为与主窗口中绝对坐标相对应的“相对”偏移量

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>
上面只对X进行变换,但是您可以通过为每个坐标使用单独的转换器类来扩展它以同时进行X和Y变换


关于上面的一个注意事项:转换只会在加载时运行一次。如果文本块正在移动,并且您需要连续执行转换,那么您可能需要发挥创造性。:)

也许你需要这个

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(Patren MVVM): 您需要写入转换器和属性Canvas.Left和Canvas.Top使用绑定。它比以前更多的代码

转换器示例(示例6)

在转换器中,需要发送两个参数sender.renderTransferMorigin.X和ActualWidth


使用一些参数观察转换器(俄语)

您是否希望
TextBlock
的位置在运行时移动(需要重新计算其渲染转换),还是在窗口/TextBlock首次加载时只需一次性移动?@McGarnagle,实际上文本的收集是动态地从数据源来的,我需要在窗口加载后动态定位文本(例如,简单情况下,如果用户在文本框中输入文本和位置,它应该根据输入显示在画布上),顺便问一下,为什么WPF中的这个过程如此复杂?我来自winform方面,现在正在研究WPF:-)事实上,可能有一种更简单的方法,可以使用面板或其他东西(例如,给元素一个绝对位置,通常应该使用画布)。换句话说,正如他们所说,您可能提出了一个“XY问题”。我的答案看起来绝对像是一个过于复杂的破解。但我想知道,文本位置是一个重要的功能,它是如何正确地放置在绝对点上的,比如Moveto(5,5)@Robin,我没有听你的评论。。。我以为您想将TextBlock中的一个相对点“拖动”到窗口中的一个绝对位置?@@McGarnagle,不,不,我只是想将TextBlock(假设现在中心点是参照点)移动到画布中的某个位置。它可能是(5,10)或其他东西。当我说移到(5,10)时,文本块应该移到(5,10),这意味着(5,10)处的中心参考点…@Robin对,这是我的理解。我相信上述方法可以做到这一点(好的,仅适用于X坐标,但这应该是正确的原则)。@@McGarnagle,谢谢,我将尝试并将其标记为答案。顺便问一下,为什么这个过程在WPF中如此复杂?我来自Winform端,现在正在了解WPF:-)@@m4a,这是一个很好的解决方案,我将根据我的要求修改答案,但是如果我想将所有元素移动到某一点,请您解释如何将此解决方案集成到XAML中?非常好,实际上,我遵循的是MVVM模式。我有Google translate:P。非常感谢@m4a,例如,通常我可以在将控件仅放置到画布后了解UIElement的实际宽度。在这种情况下,如果我想把控制直接放在某个点上,hw怎么做?
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);
}