zoukankan      html  css  js  c++  java
  • WPF中Popup的几个问题

    要用popup控件来解决一些问题。就此带来了一批问题。

    问题一、 在popup外任意位置点击时要能关闭popup,这个本来简单,只要加上StaysOpen=false就可以了。但我的popup中有个OpenFileDialog控件,这个控件窗口一打开,popup就被关闭了。

    解决:

    在btnOpenFile按钮的PreviewMouseLeftButtonDown事件里添加了

    ((Popup)((FrameworkElement)this.Parent).Parent).StaysOpen = true;

    问题二、 StaysOpen设置为True后,点击按钮变成了这样。popup是TopMost的,挡在了文件窗口前面。

    解决:

    无法简单解决这个问题,只好采用github上的一个NonTopmostPopup自定义控件取代Popup。

    为了在关闭文件选择窗口后popup仍然能够在鼠标点击App任意位置时被关闭,在btnOpenFile按钮的Click事件里添加了

    ((Popup)((FrameworkElement)this.Parent).Parent).StaysOpen = false;

    问题三、上述做法的结果是,如果双击文件名时的鼠标位置在popup区域以外,popup还是会直接关闭。因为双击位置的主窗口控件虽然被文件对话框遮挡,但仍会触发MouseLeftButtonUp(或MouseUp)事件,这可能算是文件对话框的一个bug。我猜是因为双击实际上是在第二次点击的MouseDown事件发生后就生效,对话框就关闭了,再往后还有MouseUp事件,却已经处于没有遮挡的裸奔状态了,当然控件们纷纷响应。

    没办法,想workaround吧。我的做法是取消按钮Click事件StaysOpen=false,改在主窗口的MouseLeftButtonDown中加下面的代码遍历控件,遇到popup就设置StaysOpen=false。

    复制代码
            private void TheShell_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
            {
                FindPopupAndClose(TheShell);
            }
    
            // Enumerate all the descendants of the visual object.
            static public void FindPopupAndClose(Visual myVisual)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(myVisual); i++)
                {
                    // Retrieve child visual at specified index value.
                    Visual childVisual = (Visual)VisualTreeHelper.GetChild(myVisual, i);
    
                    // Do processing of the child visual object.
                    if (childVisual is Popup)
                        ((Popup)childVisual).StaysOpen = false;
                    // Enumerate children of the child visual object.
                    FindPopupAndClose(childVisual);
                }
            }
    复制代码

    问题四、一些情况下,我需要popup StaysOpen=false,并且能跟随主窗口移动而移动(默认情况popup是不动的)。

    解决:

    参考StackOverFlow上的帖子,在codebehind加下面事件:

    复制代码
    public partial class View1 : UserControl
    {
        // Constructor
        public View1()
        {
            InitializeComponent();
    
            // Window.GetWindow() will return Null if you try to call it here!             
    
            // Wire up the Loaded handler instead
            this.Loaded += new RoutedEventHandler(View1_Loaded);
        }
    
        /// Provides a way to "dock" the Popup control to the Window
        ///  so that the popup "sticks" to the window while the window is dragged around.
        void View1_Loaded(object sender, RoutedEventArgs e)
        {
            Window w = Window.GetWindow(popupTarget);
            // w should not be Null now!
            if (null != w)
            {
                w.LocationChanged += delegate(object sender2, EventArgs args)
                {
                    var offset = myPopup.HorizontalOffset;
                    // "bump" the offset to cause the popup to reposition itself
                    //   on its own
                    myPopup.HorizontalOffset = offset + 1;
                    myPopup.HorizontalOffset = offset;
                };
                // Also handle the window being resized (so the popup's position stays
                //  relative to its target element if the target element moves upon 
                //  window resize)
                w.SizeChanged += delegate(object sender3, SizeChangedEventArgs e2)
                {
                    var offset = myPopup.HorizontalOffset;
                    myPopup.HorizontalOffset = offset + 1;
                    myPopup.HorizontalOffset = offset;
                };
            }
        }
    }
  • 相关阅读:
    C++ map详解
    C++ vector和list的区别
    C++静态存储,动态存储
    C++文件输入和输出
    C/C++数组名与指针的区别详解
    C++运算符重载详解
    poj3177Redundant Paths tarjan缩点
    C++编译过程与内存空间
    [JAVA &#183; 0基础]:19.容器类
    FFmpeg总结(六)AV系列结构体之AVPacket
  • 原文地址:https://www.cnblogs.com/sjqq/p/7835093.html
Copyright © 2011-2022 走看看