【问题标题】:Silverlight - Determine if a UIElement is visible on screenSilverlight - 确定 UIElement 在屏幕上是否可见
【发布时间】:2014-10-09 00:04:28
【问题描述】:

我的应用程序中有一个包含两个选项卡的选项卡控件的表单。在其中一个选项卡中,我有一个 UIElement。当鼠标悬停在它上面时,会启动一个计时器,并在一秒钟后执行一些功能。

问题是当鼠标悬停并立即切换选项卡时,我需要停止计时器。我无法在选项卡控件事件中执行此操作(选项卡控件无法识别计时器)。我希望能够知道此 UIElement 何时在屏幕上不可见(切换选项卡时可见性属性仍然可见)。

这就是它的样子:

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

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

【问题讨论】:

    标签: c# silverlight


    【解决方案1】:

    AFAIK,没有可靠的方法来测试元素是否可见。

    在 Silverlight 中,可以通过多种方式隐藏元素(在屏幕外、被 ScrollViewer 遮挡、被另一个元素重叠、完全透明、被着色器效果扭曲等)和取消隐藏(指定 Z -order,指定自定义渲染变换,通过逆效果重叠等)

    以下两种解决方法可能符合您的要求,也可能不符合您的要求:

    1. 如果您尝试执行类似于工具提示的操作,请将处理程序添加到 UIElement 的 MouseLeave 事件。在这种情况下,如果计时器处于活动状态,请将其停止。

    2. 或者,在 dt_Tick 处理程序中,您可以通过检查 TabControl.SelectedIndex 属性来检查显示哪个选项卡,如果选择了错误的选项卡,则忽略此事件。

    更新:这是#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
    }
    

    【讨论】:

    • 感谢您的回答。我真的在尝试做类似工具提示的事情,但是在鼠标离开时停止计时器并不能解决问题(鼠标离开没有被触发)。在 dt_tick 内部,我无法检查活动选项卡,因为它是我的应用程序中所有 UIElements 的通用类
    【解决方案2】:

    您可以通过 Unloaded 事件解决此问题。每当 VisualTree 发生更改导致元素成为当前未呈现的 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
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-15
      • 1970-01-01
      • 2015-03-29
      • 1970-01-01
      相关资源
      最近更新 更多