如果圆大于canvas,防止圆超出canvas/window?
Prevent circle of going out of the canvas/window if circle is bigger than canvas?
万一圆比 canvas 大,我怎样才能防止圆不超出 canvas/window?
我需要它自动调整到最大可用尺寸。解决此问题的最佳解决方案是什么?我知道使用拖动功能可以解决这个问题,但我需要点击 2 次才能完成。第一次单击将定义中心点,第二次单击定义半径。
WPFxaml代码
<Window x:Class="ShapeAnimator.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:ShapeAnimator"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button Content="Step" HorizontalAlignment="Left" Margin="10,390,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="90,390,0,0" VerticalAlignment="Top" Width="75"/>
<Canvas Name="Canvas1"
Background="#000000"
HorizontalAlignment="Left" Height="376" VerticalAlignment="Top" Width="792"
MouseDown="Canvas1_MouseDown"
/>
<Label
Name="CoordLabel"
Content="Label" HorizontalAlignment="Left" Margin="708,383,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.362,0.083"/>
</Grid>
</Window>
和.cs
using System;
using System.Collections.Generic;
using System.Linq;
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 ShapeAnimator
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
int ClickStep = 1;
double x1, y1;
List<Circle> circles = new List<Circle>();
private Animator animator;
public MainWindow()
{
InitializeComponent();
animator = new Animator((int)Canvas1.Width, (int)Canvas1.Height);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
foreach(Circle c in circles)
{
animator.Animate(c);
}
RefreshScreen();
}
private void Canvas1_MouseDown(object sender, MouseButtonEventArgs e)
{
double x = Mouse.GetPosition(Canvas1).X;
double y = Mouse.GetPosition(Canvas1).Y;
CoordLabel.Content = x.ToString() + ":" + y.ToString();
if (ClickStep > 0)
{
x1 = x;
y1 = y;
DrawCircle(x1, y1, 3);
}
else
{
double radius = Math.Sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
Circle c = new Circle(x1, y1, radius);
circles.Add(c);
RefreshScreen();
}
ClickStep = -ClickStep;
}
private void RefreshScreen()
{
ClearScreen();
foreach(Circle c in circles)
{
DrawCircle(c.x, c.y, c.radius);
}
}
private void ClearScreen()
{
Canvas1.Children.Clear();
}
private void DrawCircle(double x, double y, double radius)
{
Ellipse c = new Ellipse()
{
Width = radius * 2,
Height = radius * 2,
Stroke = Brushes.Red,
StrokeThickness = 1
};
Canvas1.Children.Add(c);
c.SetValue(Canvas.LeftProperty, x - radius);
c.SetValue(Canvas.TopProperty, y - radius);
}
}
}
不确定为什么拖动会修复它,但可以肯定的是,当第一次点击完成时,您可以知道它的位置,因此可以知道到 canvas 的所有 4 个边缘的最短距离,因此您可以计算出最大可能的半径。在第一次点击或第二次点击时,进行计算,计算半径,如果半径大于最大值,则减小半径。例如:
else
{
double radius = Math.Sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
if(radius > x1)
radius = x1;
if(radius > y1)
radius = y1;
if(radius > Canvas1.Width - x1)
radius = Canvas1.Width - x1;
if(radius > Canvas1.Height - y1)
radius = Canvas1.Height - y1;
在这 4 个 if 语句之后,半径将以距边缘的最小距离结束
ps;请将您的控件命名为比 Canvas1、Textbox1 等更合适的名称 - 当程序拥有大量控件时,它们会变得非常难以理解,所有控件都称为 TypenameN
万一圆比 canvas 大,我怎样才能防止圆不超出 canvas/window?
我需要它自动调整到最大可用尺寸。解决此问题的最佳解决方案是什么?我知道使用拖动功能可以解决这个问题,但我需要点击 2 次才能完成。第一次单击将定义中心点,第二次单击定义半径。
WPFxaml代码
<Window x:Class="ShapeAnimator.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:ShapeAnimator"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button Content="Step" HorizontalAlignment="Left" Margin="10,390,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="90,390,0,0" VerticalAlignment="Top" Width="75"/>
<Canvas Name="Canvas1"
Background="#000000"
HorizontalAlignment="Left" Height="376" VerticalAlignment="Top" Width="792"
MouseDown="Canvas1_MouseDown"
/>
<Label
Name="CoordLabel"
Content="Label" HorizontalAlignment="Left" Margin="708,383,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.362,0.083"/>
</Grid>
</Window>
和.cs
using System;
using System.Collections.Generic;
using System.Linq;
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 ShapeAnimator
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
int ClickStep = 1;
double x1, y1;
List<Circle> circles = new List<Circle>();
private Animator animator;
public MainWindow()
{
InitializeComponent();
animator = new Animator((int)Canvas1.Width, (int)Canvas1.Height);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
foreach(Circle c in circles)
{
animator.Animate(c);
}
RefreshScreen();
}
private void Canvas1_MouseDown(object sender, MouseButtonEventArgs e)
{
double x = Mouse.GetPosition(Canvas1).X;
double y = Mouse.GetPosition(Canvas1).Y;
CoordLabel.Content = x.ToString() + ":" + y.ToString();
if (ClickStep > 0)
{
x1 = x;
y1 = y;
DrawCircle(x1, y1, 3);
}
else
{
double radius = Math.Sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
Circle c = new Circle(x1, y1, radius);
circles.Add(c);
RefreshScreen();
}
ClickStep = -ClickStep;
}
private void RefreshScreen()
{
ClearScreen();
foreach(Circle c in circles)
{
DrawCircle(c.x, c.y, c.radius);
}
}
private void ClearScreen()
{
Canvas1.Children.Clear();
}
private void DrawCircle(double x, double y, double radius)
{
Ellipse c = new Ellipse()
{
Width = radius * 2,
Height = radius * 2,
Stroke = Brushes.Red,
StrokeThickness = 1
};
Canvas1.Children.Add(c);
c.SetValue(Canvas.LeftProperty, x - radius);
c.SetValue(Canvas.TopProperty, y - radius);
}
}
}
不确定为什么拖动会修复它,但可以肯定的是,当第一次点击完成时,您可以知道它的位置,因此可以知道到 canvas 的所有 4 个边缘的最短距离,因此您可以计算出最大可能的半径。在第一次点击或第二次点击时,进行计算,计算半径,如果半径大于最大值,则减小半径。例如:
else
{
double radius = Math.Sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
if(radius > x1)
radius = x1;
if(radius > y1)
radius = y1;
if(radius > Canvas1.Width - x1)
radius = Canvas1.Width - x1;
if(radius > Canvas1.Height - y1)
radius = Canvas1.Height - y1;
在这 4 个 if 语句之后,半径将以距边缘的最小距离结束
ps;请将您的控件命名为比 Canvas1、Textbox1 等更合适的名称 - 当程序拥有大量控件时,它们会变得非常难以理解,所有控件都称为 TypenameN