简体   繁体   English

Silverlight - 确定屏幕上是否显示UIElement

[英]Silverlight - Determine if a UIElement is visible on screen

I have a form in my application with a tab control containing two tabs. 我的应用程序中有一个表单,其中包含两个选项卡的选项卡控件。 in one of the tabs I have a UIElement. 在其中一个标签中,我有一个UIElement。 When mouse hover on it a timer is started, and after a second some functionality is performed. 当鼠标悬停在其上时,启动计时器,并在一秒钟后执行某些功能。

The problem is when hovering with the mouse and immediately switching tab, than I need to stop the timer. 问题是当鼠标悬停并立即切换标签时,我需要停止计时器。 doing it in the tab control events is not possible to me (the tab control does not recognize the timer). 我无法在标签控件事件中执行此操作(标签控件无法识别计时器)。 I want to be able to know when this UIElement is not visible on screen (Visibility property is still Visible when switching tabs). 我希望能够知道何时在屏幕上看不到此UIElement(切换选项卡时Visibility属性仍然可见)。

This is how it looked: 这就是它的样子:

private void element_MouseEnter(object sender, MouseEventArgs e) 
    {            
        timer.Start() 
    }

private void dt_Tick(object sender, EventArgs e) 
    {       
       //Some functionality
    }

AFAIK, there is no reliable way to test if the element is visible or not. AFAIK,没有可靠的方法来测试元素是否可见。

In Silverlight, there are too many ways why an element can be hidden (outside of the screen, obscure by ScrollViewer, overlap by another element, make completely transparent, distort by a shader effect, etc.) and unhidden (specify Z-order, specify custom render transform, overlap by inverse effect, etc.) 在Silverlight中,有太多方法可以隐藏元素(在屏幕之外,ScrollViewer模糊,由另一个元素重叠,完全透明,由着色器效果扭曲等)和unhidden(指定Z顺序,指定自定义渲染变换,按反效果重叠等)

Here are two workarounds that may or may not fit your requirements: 以下是两种可能符合您要求的解决方法:

  1. If you're trying to do something similar to tooltip, add handler to MouseLeave event for your UIElement. 如果您尝试执行类似于工具提示的操作,请为UIElement的MouseLeave事件添加处理程序。 In that event, if the timer is active, stop it. 在那种情况下,如果计时器处于活动状态,请将其停止。

  2. Alternatively, inside dt_Tick handler you can check which tab is shown by checking the TabControl.SelectedIndex property, if the wrong one is selected just ignore this event. 或者,在dt_Tick处理程序中,您可以通过检查TabControl.SelectedIndex属性来检查显示哪个选项卡,如果选择了错误的选项,则忽略此事件。

Update: here's some sample code (untested) for the #2: 更新:这里是#2的一些示例代码(未经测试):

public static IEnumerable<FrameworkElement> visualParents( this FrameworkElement e )
{
    DependencyObject obj = e;
    while( true )
    {
        obj = VisualTreeHelper.GetParent( obj );
        if( null == obj ) yield break;
        FrameworkElement fwe = obj as FrameworkElement;
        if( null != fwe ) yield return fwe;
    }
}

public static bool isOnVisibleTab( FrameworkElement elt )
{
    TabItem item = elt.visualParents().OfType<TabItem>().FirstOrDefault();
    if( null == item )
        return true;         // Did not find the tab, return true
    return item.IsSelected;  // Found the tab, return true if the tab is selected
}

You can solve this with the Unloaded event. 您可以使用Unloaded事件解决此问题。 It is raised whenever changes to the VisualTree happen that result in the Element being part of a VisualTree branch that is not currently rendered. 只要对VisualTree发生更改,就会引发它,导致Element成为当前未呈现的VisualTree分支的一部分。

private void element_MouseEnter(object sender, MouseEventArgs e) 
{            
    timer.Start();
    element.Unloaded += OnElementUnloaded;
}

private void OnElementUnloaded(object sender, EventArgs e)
{
    element.Unloaded -= OnElementUnloaded;
    timer.Stop();
}

private void dt_Tick(object sender, EventArgs e) 
{
    element.Unloaded -= OnElementUnloaded;
   //Some functionality
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM