随着窗口大小的变化,如何在wpf中动态测量网格宽度/高度
Posted
技术标签:
【中文标题】随着窗口大小的变化,如何在wpf中动态测量网格宽度/高度【英文标题】:how to measure grid width/height in wpf dynamically as the window size changes 【发布时间】:2013-02-05 16:42:50 【问题描述】:我想要做的总体是在画布上添加一个椭圆,以表示当高尔夫球推杆从该圆的中心以某个角度击打高尔夫球时,它在圆的圆周上的位置。为此,我使用了两个图像,其中一个是一个分成多个部分的圆圈来表示球被击中的角度。另一个图像只是一个旋转的推杆头,以表示球杆击球的角度。此图像位于圆形图像的顶部。蓝色椭圆代表球的位置。在下面的链接中查看我的应用程序的图像输出:
Required application output
为此,我基本上使用以下代码计算了网格的宽度和高度:
public FacePage()
InitializeComponent();
GridGraphs.SizeChanged += GridGraphs_SizeChanged;
void GridGraphs_SizeChanged(object sender, SizeChangedEventArgs e)
GetMeasurements();
private void GetMeasurements()
GridGraphs.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
double width = GridGraphs.DesiredSize.Width;
double height = GridGraphs.DesiredSize.Height;
RotatePutter(width, height);
然后将宽度和高度传递给RotatePutter(),其中宽度和高度除以二得到网格的中心点,如下所示:
public void RotatePutter(double width, double height)
double radius = width * 0.5;
double centerX = width * 0.5;
double centerY = height * 0.5;
Random ran = new Random();
double angle = ran.Next(-15, 15);
if (angle >= 0)
if (angle <= 5)
lblShotStaus.Content = "Square";
else
lblShotStaus.Content = "Open";
else
lblShotStaus.Content = "Closed";
double angleradians = (angle * (Math.PI / 180));
Point putterCentre = new Point(0.5, 0.5);
imgPutter.RenderTransformOrigin = putterCentre;
RotateTransform rt = new RotateTransform(angle, 0.5, 0.5);
imgPutter.RenderTransform = rt;
BallLocation(radius, angleradians, centerX, centerY);
中心点,半径,角度和推杆图像在这里旋转,半径,角度弧度,centerX和centerY被传递给BallLocation来计算Ball的位置,如下所示:
public void BallLocation(double rad, double anglerad, double centerX, double centerY)
Ellipse ellipse = new Ellipse();
double xBallPoint = (centerX - (rad * Math.Cos(anglerad)));
double yBallPoint = (centerY - (rad * Math.Sin(anglerad)));
ellipse.Height = 10;
ellipse.Width = 10;
ellipse.Fill = new SolidColorBrush(Colors.Aqua);
Canvas.SetLeft(ellipse, xBallPoint);
Canvas.SetTop(ellipse, yBallPoint);
canvasFaceAngle.Children.Add(ellipse);
这在全屏下工作正常,一旦我改变窗口的大小,球的位置对于它被击中的角度是完全错误的。
有没有人知道如何随着窗口大小的变化动态获取网格宽度和高度,以便计算椭圆(球)的正确位置。或者也欢迎任何其他完成此操作的替代方式。提前致谢。
这是我的 xaml:
<UserControl x:Class="HoleMorePuttsApplication.Pages.FacePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40*"/>
<ColumnDefinition Width="60*"/>
</Grid.ColumnDefinitions>
<Viewbox Grid.ColumnSpan="1">
<Label Content="Face Angle Page" FontWeight="Bold" />
</Viewbox>
<Grid Name="GridGraphs" Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Name="columnLeft" Width="50*"/>
<ColumnDefinition Name="columnRight" Width="50*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Name="rowTop" Height="70*"/>
<RowDefinition Name="rowBottom" Height="30*"/>
</Grid.RowDefinitions>
<Image x:Name="imgAngles" Source="C:\Users\BernardWork\Documents\Work\Net\PuttingApp\Images\360Angles.jpg" Grid.ColumnSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Image x:Name="imgPutter" Source="C:\Users\BernardWork\Documents\Work\Net\PuttingApp\Images\Putter.jpg" Opacity="0.5" Margin="130,105,70,105" Grid.ColumnSpan="2" HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
<Label x:Name="lblShotStaus" Content="Label" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
<Canvas Name="canvasFaceAngle" Grid.ColumnSpan="2" Grid.Row="0" RenderTransformOrigin="0.543,0.511"></Canvas>
</Grid>
</Grid>
【问题讨论】:
【参考方案1】:如果我理解正确,我相信问题可能出在:
double width = GridGraphs.DesiredSize.Width;
double height = GridGraphs.DesiredSize.Height;
您调用 Measure 时没有提供任何边界,这意味着它会告诉您 Grid
的大小如果没有限制(因此,DesiredSize
)。 DesiredSize
和 ActualSize
可能是两个非常不同的值。
在上述情况下,SizeChanged
方法的参数将为您提供所需的内容。
void GridGraphs_SizeChanged(object sender, SizeChangedEventArgs e)
RotatePutter(e.NewSize.Width, e.NewSize.Height);
【讨论】:
嗨,谢谢你的回复,你是对的,问题在于双宽度 = GridGraphs.DesiredSize.Width;双倍高度 = GridGraphs.DesiredSize.Height; 嗨,谢谢你的回复,你是对的,问题在于双宽度 = GridGraphs.DesiredSize.Width;双倍高度 = GridGraphs.DesiredSize.Height;我将其更改为使用画布 ActualWidth 和 ActualHeight 并且它正在工作,但是你提出的答案也很有效。再次感谢 不客气,很高兴它成功了。请将此标记为答案,以便其他人也可以从中受益。【参考方案2】:因此,如果目标只是获取网格宽度/高度,ActualWidth 和 ActualHeight 属性应该会为您提供该信息。不过需要注意的一件事是:当 Grid 控件随窗口一起改变大小时,Canvas 控件不会。换句话说,如果你读取一个网格的实际宽度/高度,它应该对应于窗口的一侧,但如果你读取一个画布的实际宽度/高度,它可能会给你错误的信息。
【讨论】:
感谢您的回答,但我最终使用了画布来获取实际的宽度和高度,并且它起作用了。这可能是因为画布被设置为拉伸以填充网格.再次感谢您的回复,非常感谢。以上是关于随着窗口大小的变化,如何在wpf中动态测量网格宽度/高度的主要内容,如果未能解决你的问题,请参考以下文章
c# winform groupbox上动态生成的控件,如何让控件随着分辨率变化而自动调整位置和大小