//xaml
<Window x:Class="WpfApp182.MainWindow"
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:WpfApp182"
mc:Ignorable="d"
KeyDown="Window_KeyDown"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Path x:Name="triPath" Fill="Red">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="0,0" IsClosed="True">
<LineSegment Point="20,0"/>
<LineSegment Point="10,50"/>
</PathFigure>
</PathGeometry>
</Path.Data>
<Path.RenderTransform>
<TransformGroup>
<TranslateTransform x:Name="translater"
X="{Binding TX,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Y="{Binding TY,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<RotateTransform x:Name="rotater"
CenterX="{Binding TCenterX,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
CenterY="{Binding TCenterY,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
<Ellipse Width="{Binding ElpRadius,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Height="{Binding ElpRadius,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Stroke="Blue"
StrokeThickness="5"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Panel.ZIndex="-1"/>
</Grid>
</Window>
//xaml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp182
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
this.Loaded += MainWindow_Loaded;
this.SizeChanged += MainWindow_SizeChanged;
}
private void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e)
{
Init();
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Init();
}
private double tCenterX;
public double TCenterX
{
get
{
return tCenterX;
}
set
{
if(value!=tCenterX)
{
tCenterX = value;
OnPropertyChanged(nameof(TCenterX));
}
}
}
private double tCenterY;
public double TCenterY
{
get
{
return tCenterY;
}
set
{
if(value!=tCenterY)
{
tCenterY = value;
OnPropertyChanged(nameof(TCenterY));
}
}
}
private double tX;
public double TX
{
get
{
return tX;
}
set
{
if(value!=tX)
{
tX = value;
OnPropertyChanged(nameof(TX));
}
}
}
private double tY;
public double TY
{
get
{
return tY;
}
set
{
if(value!=tY)
{
tY = value;
OnPropertyChanged(nameof(TY));
}
}
}
private Point elpCenter;
public Point ElpCenter
{
get
{
return elpCenter;
}
set
{
if (value != elpCenter)
{
elpCenter = value;
OnPropertyChanged(nameof(ElpCenter));
}
}
}
private double elpRadius;
public double ElpRadius
{
get
{
return elpRadius;
}
set
{
if(value!=elpRadius)
{
elpRadius = value;
OnPropertyChanged(nameof(ElpRadius));
}
}
}
private bool isPaused = false;
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propName="")
{
var handler = PropertyChanged;
if(handler!=null)
{
handler?.Invoke(this, new PropertyChangedEventArgs(propName));
}
}
private System.Timers.Timer tmr { get; set; }
private void Init()
{
var fe = this.Content as FrameworkElement;
if (fe != null)
{
TCenterX= fe.ActualWidth / 2;
TCenterY = fe.ActualHeight / 2;
TX = fe.ActualWidth / 2 - 15;
TY = 0;
ElpCenter = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
ElpRadius = fe.ActualHeight - 50;
}
if (tmr != null)
{
return;
}
tmr = new System.Timers.Timer();
tmr.Interval = 1000;
tmr.Elapsed += Tmr_Elapsed;
tmr.Start();
}
private void Tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if(isPaused)
{
return;
}
try
{
Application.Current?.Dispatcher.BeginInvoke(new Action(() =>
{
rotater.Angle += 10;
if (rotater.Angle >= 360)
{
rotater.Angle = 0;
}
this.Title = rotater.Angle.ToString();
Console.WriteLine(Mouse.GetPosition(triPath).X + "," + Mouse.GetPosition(triPath).Y);
}));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message+"\n"+ex.StackTrace.ToString());
}
}
private void Window_KeyDown(object sender, KeyEventArgs e)
{
isPaused = !isPaused;
}
}
}
![]()
![]()
![]()
![]()