Please check the attached image. I made the textblock origin to it\'s center by RenderTransformOrigin=\"0.5,0.5\". Now I would like to move the textblock based on the refere
the textblock should move to absolute (0,0)
I assume that by "absolute" you mean "relative to the MainWindow". I don't think there's a built-in render transform to coordinates relative to another element. But, you could always use a binding for X
and Y
-- I guess it would have to be a MultiBinding to allow you to convert a) the MainWindow, b) the TextBlock, to the "relative" offset corresponding to an absolute coordinate in the MainWindow.
The XAML should be something like this (X coordinate only here, for example). You could specify the target "absolute" point in the 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>
The "TranslateConverter" is where you convert your reference (the window) and target (the TextBlock) to a relative offset. Use TransformToVisual to convert the coordinates of the TextBlock to those of the 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();
}
}
The above does the transform for X only, but you can extend it to do both X and Y by using a separate converter class for each coordinate.
One note about the above: the transformation will only run once, on load. If the TextBlock is moving around, and you need to perform the transformation continuously, then you might have to get creative. :)
Maybe you need this
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);
}
to Xaml (patern MVVM): you need write converter and for properties Canvas.Left and Canvas.Top use Binding. It's more code than previously.
Example Converter (example 6) http://www.codeproject.com/Articles/29054/WPF-Data-Binding-Part
In converter need send 2 parameters sender.RenderTransformOrigin.X and ActualWidth.
Watch Converter with some params (in russian) - http://habrahabr.ru/post/141107/