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,755 questions
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
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.
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; }
}
}
}
}
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