get the shape after applying geometry

essamce 621 Reputation points
2020-06-30T15:54:22.823+00:00

hi i have applied a render tranform to a System.Windows.Shapes.Line and i don't know how to get line X1, Y1, X2, Y2 after transform.
any help will be appreciated,
thanks in advance.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,685 questions
0 comments No comments
{count} votes

Accepted answer
  1. Peter Fleischer (former MVP) 19,231 Reputation points
    2020-06-30T21:05:39.907+00:00

    Hi, code in C#.NET:

        using System;
        using System.ComponentModel;
        using System.Runtime.CompilerServices;
        using System.Windows;
        using System.Windows.Input;
        using System.Windows.Interactivity;
        using System.Windows.Media;
        using System.Windows.Shapes;
    
        namespace WpfApp1
        {
    
        namespace WpfApp036
        {
          public class ViewModel : INotifyPropertyChanged
          {
            internal Line MyLine { get; set; }
            public double Angle { get; set; } = -10;
            public Point Point1 { get; set; }
            public Point Point2 { get; set; }
            public ICommand Cmd { get => new RelayCommand(CmdExec); }
    
            internal void CmdExec(object obj)
            {
              if (MyLine == null) return;
              Angle += 10;
              OnPropertyChanged(nameof(Angle));
              MyLine.LayoutTransform = new RotateTransform(Angle);
              var TransMatrix = MyLine.LayoutTransform.Value;
              Point1 = TransMatrix.Transform(new Point(MyLine.X1, MyLine.Y1));
              OnPropertyChanged(nameof(Point1));
              Point2 = TransMatrix.Transform(new Point(MyLine.X2, MyLine.Y2));
              OnPropertyChanged(nameof(Point2));
            }
    
            #region PropertyChanged
            public event PropertyChangedEventHandler PropertyChanged;
            internal void OnPropertyChanged([CallerMemberName] string propName = "") =>
             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
            #endregion
          }
    
          public class LineBehavior : Behavior<Line>
          {
            protected override void OnAttached()
            {
              var vm = AssociatedObject.DataContext as ViewModel;
              vm.MyLine = AssociatedObject;
              vm.CmdExec(null);
            }
          }
          public class RelayCommand : ICommand
          {
            private readonly Predicate<object> _canExecute;
            private readonly Action<object> _action;
            public RelayCommand(Action<object> action) { _action = action; _canExecute = null; }
            public RelayCommand(Action<object> action, Predicate<object> canExecute) { _action = action; _canExecute = canExecute; }
            public void Execute(object o) => _action(o);
            public bool CanExecute(object o) => _canExecute == null ? true : _canExecute(o);
            public event EventHandler CanExecuteChanged
            {
              add { CommandManager.RequerySuggested += value; }
              remove { CommandManager.RequerySuggested -= value; }
            }
          }
        }
    }
    
    1 person found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Peter Fleischer (former MVP) 19,231 Reputation points
    2020-06-30T18:07:36.73+00:00

    Hi, you can catch reference to line and use transformation matrix. Try following demo:

    <Window x:Class="Window036"  
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
            xmlns:local="clr-namespace:WpfApp1.WpfApp036"  
            xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"  
            mc:Ignorable="d"  
            Title="Window036" Height="450" Width="800">  
      <Window.DataContext>  
        <local:ViewModel/>  
      </Window.DataContext>  
      <Canvas>  
        <StackPanel Orientation="Horizontal">  
          <Button Content="Transform"  Command="{Binding Cmd}"/>  
          <StackPanel>  
            <StackPanel Orientation="Horizontal">  
              <Label Content="Angle:"/>  
              <Label Content="{Binding Angle}"/>  
            </StackPanel>  
            <StackPanel Orientation="Horizontal">  
              <Label Content="Point 1 X:"/>  
              <Label Content="{Binding Point1.X}"/>  
            </StackPanel>  
            <StackPanel Orientation="Horizontal">  
              <Label Content="Point 1 Y:"/>  
              <Label Content="{Binding  Point1.Y}"/>  
            </StackPanel>  
            <StackPanel Orientation="Horizontal">  
              <Label Content="Point 2 X:"/>  
              <Label Content="{Binding  Point2.X}"/>  
            </StackPanel>  
            <StackPanel Orientation="Horizontal">  
              <Label Content="Point 2 Y:"/>  
              <Label Content="{Binding  Point2.Y}"/>  
            </StackPanel>  
          </StackPanel>  
        </StackPanel>  
        <Line X1="230" X2="400" Y1="50" Y2="80" StrokeThickness="3" Stroke="Red">  
          <i:Interaction.Behaviors>  
            <local:LineBehavior/>  
          </i:Interaction.Behaviors>  
        </Line>  
      </Canvas>  
    </Window>  
    

    -----------------------------------------------------------------

    Imports System.ComponentModel  
    Imports System.Runtime.CompilerServices  
    Imports System.Windows.Interactivity  
      
    Namespace WpfApp036  
      
      Public Class ViewModel  
        Implements INotifyPropertyChanged  
        Friend Property MyLine As Line  
        Public Property Angle As Double = -10  
        Public Property Point1 As Point  
        Public Property Point2 As Point  
        Public ReadOnly Property Cmd As ICommand = New RelayCommand(AddressOf CmdExec)  
      
        Friend Sub CmdExec(obj As Object)  
          If MyLine Is Nothing Then Exit Sub  
          Angle += 10  
          OnPropChanged(NameOf(Angle))  
          MyLine.LayoutTransform = New RotateTransform(Angle)  
          Dim TransMatrix = MyLine.LayoutTransform.Value  
          Point1 = TransMatrix.Transform(New Point(MyLine.X1, MyLine.Y1))  
          OnPropChanged(NameOf(Point1))  
          Point2 = TransMatrix.Transform(New Point(MyLine.X2, MyLine.Y2))  
          OnPropChanged(NameOf(Point2))  
        End Sub  
      
        Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged  
        Friend Sub OnPropChanged(<CallerMemberName> Optional propName As String = "")  
          RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName))  
        End Sub  
      End Class  
      
      Public Class LineBehavior  
        Inherits Behavior(Of Line)  
        Protected Overrides Sub OnAttached()  
          Dim vm = TryCast(AssociatedObject.DataContext, ViewModel)  
          vm.MyLine = AssociatedObject  
          vm.CmdExec(Nothing)  
        End Sub  
      End Class  
      
    End Namespace  
    

    11030-30-06-2020-20-08-54.gif

    1 person found this answer helpful.