我希望获得嵌入TextBlock
的{{1}}的屏幕位置和可见性 - 例如PivotItem
的屏幕位置和可见性:
TB2
对于其他Xaml控件,我使用以下代码实现了这一点:
<phone:Pivot>
<phone:PivotItem Header="first">
<TextBlock x:Name="TB1" Text="Hello 1"></TextBlock>
</phone:PivotItem>
<phone:PivotItem Header="second" >
<TextBlock x:Name="TB2" Text="Hello 2"></TextBlock>
</phone:PivotItem>
<phone:PivotItem Header="three" >
<TextBlock x:Name="TB3" Text="Hello 3"></TextBlock>
</phone:PivotItem>
</phone:Pivot>
但是,对于 public static Rect Position(this FrameworkElement element)
{
if (element.Visibility == Visibility.Collapsed)
return Rect.Empty;
if (element.Opacity < 0.01)
return Rect.Empty;
// Obtain transform information based off root element
GeneralTransform gt = element.TransformToVisual(Application.Current.RootVisual);
// Find the four corners of the element
Point topLeft = gt.Transform(new Point(0, 0));
Point topRight = gt.Transform(new Point(element.RenderSize.Width, 0));
Point bottomLeft = gt.Transform(new Point(0, element.RenderSize.Height));
Point bottomRight = gt.Transform(new Point(element.RenderSize.Width, element.RenderSize.Height));
var left = Math.Min(Math.Min(Math.Min(topLeft.X, topRight.X), bottomLeft.X), bottomRight.X);
var top = Math.Min(Math.Min(Math.Min(topLeft.Y, topRight.Y), bottomLeft.Y), bottomRight.Y);
var position = new Rect(left, top, element.ActualWidth, element.ActualHeight);
return position;
}
子项,当PivotItem
在屏幕外时,此计算不会提供预期的答案。相反,它会在屏幕上向后滑动PivotItem
时提供项目在屏幕上显示的位置的答案。在转换过程中,我可以看到使用上述方法正确计算位置 - 例如在转换过程中,我会看到位置从屏幕的左/右正确滑动。
我查看了其他属性,例如PivotItem
和Visible
,看看这里是否有其他机制用于隐藏屏幕外的PivotItem或其中一个Opacity
, Parent
等等 - 但所有这些似乎都会产生GrandParent
和Visible
个结果。
我还尝试迭代VisualTree,看看是否有任何具有纯色背景的元素屏蔽了“屏幕外”Opacity == 1.0
- 但我在树中看不到任何元素。
这里还有其他一些属性需要考虑吗? PivotItem
内容在“屏幕外”时是如何隐藏的?如果我真的需要,我知道我可以使用PivotItem
的{{1}}属性来尝试帮助进行SelectedIndex
位置计算,但我希望避免{{1}如果可以的话 - 如果可能的话,我更愿意使用通用的Xaml和VisualTree方法来获得这个位置。
答案 0 :(得分:1)
我调查了一下,但我找不到他们是如何隐藏PivotItems的。我猜这个位置是正确的,但是这个项目并不是因为未知(对我而言)的原因。稍后我会再次研究它,但是现在我想提一些我注意到的其他潜在问题。
你不应该在右下角使用Math.Max吗?原因是 - ActualHeight和ActualWidth不是旋转感知的。
RenderSize.Width / Height和ActualWidth / Height不同。我不确定将它们用于计算是个好主意。
您是否需要检查元素上方可视树中的所有内容,以确定它是否实际可见?
编辑:我查看了Microsoft.Phone.dll的反编译源(这是带有Pivot控件的dll),我找不到任何关于如何隐藏PivotItem的内容。但是有一些本机方法调用。
答案 1 :(得分:0)
我对您的代码做了一些更改,并给出了UIElement的真实位置
XAML:
<Grid x:Name="LayoutRoot" Background="Transparent">
<!--Pivot Control-->
<phone:Pivot x:Name="MyPivot">
<phone:PivotItem Header="first" x:Name="first">
<TextBlock x:Name="TB1" FontSize="30" Text="Hello 1" Tap="TB1_Tap"></TextBlock>
</phone:PivotItem>
<phone:PivotItem Header="second" x:Name="second">
<TextBlock x:Name="TB2" FontSize="50" Height="66" Width="155" Margin="20" Text="Hello 2" Tap="TB2_Tap"></TextBlock>
</phone:PivotItem>
<phone:PivotItem Header="three" x:Name="three">
<TextBlock x:Name="TB3" Text="Hello 3"></TextBlock>
</phone:PivotItem>
</phone:Pivot>
</Grid>
CS:
public partial class PivotPage1 : PhoneApplicationPage
{
public PivotPage1()
{
InitializeComponent();
}
private void TB1_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
Rect r = Pos.MyPosition(TB1,first);
string str = "Left" + r.Left.ToString() + "\nTop:" + r.Top.ToString() + "\nRight:" + r.Right.ToString() + "\nBottom:" + r.Bottom.ToString() + "\nHeight:" + r.Height.ToString() + "\nWidth" + r.Width.ToString();
MessageBox.Show(str);
}
private void TB2_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
Rect r = Pos.MyPosition(TB2,second);
string str = "Left" + r.Left.ToString() + "\nTop:" + r.Top.ToString() + "\nRight:" + r.Right.ToString() + "\nBottom:" + r.Bottom.ToString() + "\nHeight:" + r.Height.ToString() + "\nWidth" + r.Width.ToString();
MessageBox.Show(str);
}
}
public static class Pos
{
public static Rect MyPosition(FrameworkElement child,FrameworkElement parent)
{
if (child.Visibility == Visibility.Collapsed)
return Rect.Empty;
if (child.Opacity < 0.01)
return Rect.Empty;
// Obtain transform information based off root child
GeneralTransform gt = child.TransformToVisual(parent);
// Find the four corners of the child
Point topLeft = gt.Transform(new Point(0, 0));
Point topRight = gt.Transform(new Point(child.RenderSize.Width, 0));
Point bottomLeft = gt.Transform(new Point(0, child.RenderSize.Height));
Point bottomRight = gt.Transform(new Point(child.RenderSize.Width, child.RenderSize.Height));
var left = Math.Min(Math.Min(Math.Min(topLeft.X, topRight.X), bottomLeft.X), bottomRight.X);
var top = Math.Min(Math.Min(Math.Min(topLeft.Y, topRight.Y), bottomLeft.Y), bottomRight.Y);
var position = new Rect(left, top, child.ActualWidth, child.ActualHeight);
return position;
}
}