打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
WPF中获取动态添加控件的ActualHeight和相对坐标

WPF中获取动态添加控件的ActualHeight和相对坐标

分类: WPF1526人阅读评论(1)收藏举报

      在WPF中有时会用到获取控件的ActualHeight,从而进行相关运算,我是需要在一个UniformGrid中动态的添加Button,然后获取 Button的ActualHeight和相对于UniformGrid的坐标。测试项目代码如下(VS2010):
    XAML部分:

  1. <Window x:Class="WpfApplication2.MainWindow"  
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.         Title="MainWindow" Height="450" Width="525">  
  5.     <Grid>  
  6.         <Grid.ColumnDefinitions>  
  7.             <ColumnDefinition/>  
  8.         </Grid.ColumnDefinitions>  
  9.         <Grid.RowDefinitions>  
  10.             <RowDefinition Height="*"/>  
  11.             <RowDefinition Height="5*"/>  
  12.         </Grid.RowDefinitions>  
  13.         <Button Name="btnTest" Grid.Column="0" Grid.Row="0" Height="50" Click="btnTest_Click">TestHeight</Button>  
  14.         <UniformGrid Name="ufg" Height="300" Grid.Row="1" Margin="0,21">  
  15.         </UniformGrid>  
  16.     </Grid>  
  17. </Window>   

     C#部分:

[c-sharp] view plaincopy?
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Windows;  
  6. using System.Windows.Controls;  
  7. using System.Windows.Data;  
  8. using System.Windows.Documents;  
  9. using System.Windows.Input;  
  10. using System.Windows.Media;  
  11. using System.Windows.Media.Imaging;  
  12. using System.Windows.Navigation;  
  13. using System.Windows.Shapes;  
  14. namespace WpfApplication2  
  15. {  
  16.     /// <summary>  
  17.     /// Interaction logic for MainWindow.xaml  
  18.     /// </summary>  
  19.     public partial class MainWindow : Window  
  20.     {  
  21.         public MainWindow()  
  22.         {  
  23.             InitializeComponent();  
  24.         }  
  25.         private void btnTest_Click(object sender, RoutedEventArgs e)  
  26.         {  
  27.             this.ufg.Children.Clear();  
  28.             for (int i = 0; i < 20; i++)  
  29.             {  
  30.                 Button btn = new Button();  
  31.                 btn.Content = i.ToString();  
  32.                 btn.Click += new RoutedEventHandler(btn_Click);  
  33.                 this.ufg.Children.Add(btn);  
  34.             }  
  35.             Button b;  
  36.             GeneralTransform transform;  
  37.             Point thePoint;  
  38.             b = ufg.Children[10] as Button;//b的实际高度是60  
  39.             MessageBox.Show("Before UpdateUniformGrid Children[10].ActualHeight:{0}",  
  40.                              b.ActualHeight.ToString());  
  41.             transform = b.TransformToAncestor(ufg);  
  42.             thePoint = transform.Transform(new Point(0, 0));  
  43.             MessageBox.Show("Before UpdateUniformGrid the Point.Y relative to UniformGrid of Children[10](TransformToAncestor): {0}",  
  44.                             thePoint.Y.ToString());  
  45.             MessageBox.Show("Before UpdateUniformGrid the Point.Y relative to UniformGrid of Children[10](TranslatePoint):{0}",  
  46.                             b.TranslatePoint(new Point(0, 0), ufg).Y.ToString());  
  47.             ufg.UpdateLayout();//更新UniformGrid的界面,为获取ActualHeight很重要,但是获取相对坐标倒是可以没有  
  48.             MessageBox.Show("After UpdateUniformGrid Children[10].ActualHeight:{0}",  
  49.                             b.ActualHeight.ToString());  
  50.             transform = b.TransformToAncestor(ufg);  
  51.             thePoint = transform.Transform(new Point(0, 0));  
  52.             MessageBox.Show("After UpdateUniformGrid, the Point.Y relative to UniformGrid of Children[10](TransformToAncestor):{0}" ,  
  53.                             thePoint.Y.ToString());  
  54.             MessageBox.Show("After UpdateUniformGrid, the Point.Y relative to UniformGrid of Children[10](TranslatePoint):{0}",  
  55.                             b.TranslatePoint(new Point(0, 0), ufg).Y.ToString());  
  56.         }  
  57.         //UniformGrid中Button单击事件  
  58.         private void btn_Click(object sender, EventArgs e)  
  59.         {  
  60.             MessageBox.Show((sender as Button).ActualHeight.ToString());  
  61.             Button b = sender as Button;  
  62.             MessageBox.Show("the Point.Y relative to UniformGrid:{0}",  
  63.                             b.TranslatePoint(new Point(0, 0), ufg).Y.ToString());  
  64.         }  
  65.   
  66.     }  
  67. }  

       运行一下测试项目就会发现在UpdataLayout之前是得不到ActualHeight 的,但是可以得到相对坐标,而在UpdataLayout之后就可以得到ActualHeight和相对坐标。网上说WPF控件需要在Render之后才能得到ActualHeight,而UpdataLayout应该就有这个功能吧,初接触WPF,所以具体的原理还不太清楚。

      另外一个是在获取相对坐标的时,在for循环外的btnTest_Click事件中和在UniformGrid中的按钮单击事件中,使用TransformToAncestor,或TranslatePoint的方法才能得到,其实获取控件的相对坐标还有其他方法,在此不一一列出,需要的朋友可以Google一下。

附件下载(2010项目)

WPF中提供了多种布局方式,因此在布局中的定位相对于WinForm的绝对定位要灵活的多,在WPF中,控件均没有如WinForm中的Location属性,但是,对应的提供了各种设定与获取相对于承载元素的定位

一般来说,Wpf中的布局控件大多都是相对定位(网格,流式,面板等),如果我们要改变控件在布局中的位置可以用Margin,Padding等类似HTML中的方式,虽然说这种方式在WinForm也可用,但是WPF中的布局方式与灵活性已经更接近与HTML了

WPF中也保留了相对传统的布局方式,如在Canvas容器中可以用SetLeft(),SetTop()来绝对定位

关于控件定位详细具体可参考 http://msdn.microsoft.com/zh-cn/library/ms751709.aspx

下来我们来简单描述几种获取控件位置的方式,这也是很多新手容易纠结的地方

1.获取鼠标在控件中的坐标

1  //在Mouse相关的事件中的方式  2   void item_MouseDown(object sender, MouseButtonEventArgs e)3    {4     Point point = e.GetPosition(canvas); 5   } 6 7   //或者Mouse的静态方法GetPosition() 获取与指定元素相对的鼠标位置=>等同于上面 8     Point point = Mouse.GetPosition(canvas);

 

2.获取控件相对于另一控件的坐标

//将相对于此元素的某个点转换至相对于指定元素的坐标中void item_MouseDown(object sender, MouseButtonEventArgs e) {      Rectangle rectangle =sender as Rectangle;     Point point = rectangle.TranslatePoint(new Point(),canvas);  }

  

3.获取控件在Window中的坐标

Window window =  Window.GetWindow(canvas);Point  point  =  canvas.TransformToAncestor(window).Transform(new Point(0, 0));

另外,c#中还提供了控件坐标与屏幕坐标之间的转换,PointFromScreen,PointToScreen,这些就不再一一说明了

总之,根据实际情况选择最适合的方式来获取控件坐标或定位Posts - 3 Articles - 0 Comments - 0

WPF获取某控件的位置,也就是偏移量

此段示例在MSDN中可见。XAML代码如下:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >  <StackPanel Margin="16">    <StackPanel Margin="8">      <TextBlock Name="myTextBlock" Margin="4" Text="Hello, world" />    </StackPanel>  </StackPanel></Window>

1、如果只需要获取相对于其父级的偏移量,则可以使用以下方法:

// Return the offset vector for the TextBlock object.Vector vector = VisualTreeHelper.GetOffset(myTextBlock);// Convert the vector to a point value.Point currentPoint = new Point(vector.X, vector.Y);

偏移量保存在Vector对象中

2、相对灵活的方法可以使用 TransformToAncestor方法,这样可以获得相对于Window的偏移量

// Return the general transform for the specified visual object.GeneralTransform generalTransform1 = myTextBlock.TransformToAncestor(this);// Retrieve the point value relative to the parent.Point currentPoint = generalTransform1.Transform(new Point(0, 0));

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
WPF快速入门系列(1)——WPF布局概览
基于WPF的交互式绘图系统的开发
WPF控件相对位置解析
C#获取鼠标在listview右键点击单元格的内容
WPF中的静态、动态图形绘制问题
wpf inkcanvas customink 毛笔效果
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服