当前位置:  开发笔记 > Android > 正文

如何在单击另一个控件时打开WPF弹出窗口,仅使用XAML标记?

如何解决《如何在单击另一个控件时打开WPF弹出窗口,仅使用XAML标记?》经验,为你挑选了4个好方法。

我有两个控件,一个TextBlock和一个PopUp.当用户在文本块上单击(MouseDown)时,我想显示弹出窗口.我认为我可以在Popup上使用EventTrigger执行此操作,但我不能在EventTrigger中使用setter,我只能启动故事板.我想在XAML中严格执行此操作,因为这两个控件都在模板中,我不知道如何在代码中找到弹出窗口.

这是概念上我想做的,但不能,因为你不能把一个setter放在EventTrigger中(就像你可以使用DataTrigger):

Some text


    
        
    
...

当事件发生在不同的控件上时,在XAML中严格显示弹出窗口的最佳方法是什么?



1> John Melvill..:

我做了一些简单的事,但它确实有效.

我使用了一个典型的ToggleButton,我通过更改其控件模板将其重新设置为文本块.然后我将ToggleButton上的IsChecked属性绑定到弹出窗口上的IsOpen属性.Popup有一些像StaysOpen这样的属性可以让你修改关闭行为.

以下适用于XamlPad.

 
   
    
      
        Click Me Here!!
            
    
  
  
    
      I'm the popup
    
   
 


另请参阅@ Qwertie的方法 - 受此启发的更有用的版本,当您在alt-tab或弹出窗口外单击时会自动关闭弹出窗口

2> Qwertie..:

以下方法与Helge Klein相同,只是当您单击Popup外部的任何位置时弹出窗口自动关闭(包括ToggleButton本身):


    



    
        
    

"BoolInverter"用于IsHitTestVisible绑定,因此当您再次单击ToggleButton时,弹出窗口将关闭:

public class BoolInverter : MarkupExtension, IValueConverter
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is bool)
            return !(bool)value;
        return value;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Convert(value, targetType, parameter, culture);
    }
}

...它显示了将IValueConverter和MarkupExtension组合在一起的便捷技术.

我确实发现了这种技术的一个问题:当屏幕上同时出现两个弹出窗口时,WPF有问题.具体来说,如果您的切换按钮位于工具栏中的"溢出弹出窗口"中,则单击它后将打开两个弹出窗口.然后,当您单击窗口上的任何其他位置时,您可能会发现第二个弹出窗口(您的弹出窗口)将保持打开状态.那时,关闭弹出窗口很困难.用户无法再次单击ToggleButton来关闭弹出窗口,因为IsHitTestVisible为false,因为弹出窗口已打开!在我的应用程序中,我不得不使用一些黑客来缓解这个问题,例如主窗口上的以下测试,其中(以路易斯布莱克的声音说)"如果弹出窗口打开并且用户在弹出窗口外的某处点击,关闭friggin'弹出窗口.":

PreviewMouseDown += (s, e) =>
{
    if (Popup.IsOpen)
    {
        Point p = e.GetPosition(Popup.Child);
        if (!IsInRange(p.X, 0, ((FrameworkElement)Popup.Child).ActualWidth) ||
            !IsInRange(p.Y, 0, ((FrameworkElement)Popup.Child).ActualHeight))
            Popup.IsOpen = false;
    }
};
// Elsewhere...
public static bool IsInRange(int num, int lo, int hi) => 
    num >= lo && num <= hi;



3> BatteryBacku..:

怎么样:



    

请注意,它PopupButton按名称引用,反之亦然.所以x:Name="..."两者都需要,Popup而且Button.

实际上可以通过Storyboard使用本SO答案中SetProperty描述的自定义EventTrigger Action 替换内容来进一步简化



4> bendewey..:

我的MouseDown部分有一些问题,但这里有一些代码可能会让你开始.


    
        
            
                
                    
                    
                    
                        
                            Test Popup Content
                        
                    
                    
                    
                        
                            
                                
                                    
                                        
                                    
                                
                            
                        
                        
                            
                                
                                    
                                        
                                    
                                
                            
                        
                    
                
            
        
    

推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有