上下文菜单不会隐藏,直到单击操作完成 WPF 通知图标

本文关键字:操作 WPF 图标 通知 单击 菜单 隐藏 上下文 | 更新日期: 2023-09-27 18:31:46

我有一个无法解决的问题。我写了一个在托盘中工作的应用程序。一切正常,但是当我单击右键(在托盘图标上)上下文菜单打开,然后单击左按钮(在菜单项上)以执行该方法时,但是上下文菜单不会隐藏,直到此方法完成并保持在屏幕顶部。你能告诉我如何在立即单击后隐藏此上下文菜单吗?我的任务栏图标的 XAML 代码:

  <tb:TaskbarIcon Name="Tray" IconSource="ico.ico" ToolTipText="text" Visibility="Visible" TrayLeftMouseUp="ShowWindow_Click">
            <tb:TaskbarIcon.ContextMenu>
                <ContextMenu Name="ContextMenu">
                    <ContextMenu.Style>
                        <Style TargetType="{x:Type ContextMenu}">
                            <Setter Property="ItemsPanel" Value="{StaticResource MenuTPL}"/>
                        </Style>
                    </ContextMenu.Style>
                    <MenuItem x:Name="ShowWindow" Click="ShowWindow_Click" Header="show"></MenuItem>
                    <MenuItem x:Name="GetPoints" Click="Run_Click" Header="points"></MenuItem>
                    <MenuItem x:Name="Finish" Click="Zakoncz_Click" Header="exit"></MenuItem>
                </ContextMenu>
            </tb:TaskbarIcon.ContextMenu>
        </tb:TaskbarIcon>

上下文菜单不会隐藏,直到单击操作完成 WPF 通知图标

如果您有像您这样的耗时方法,则需要在另一个线程上执行它。否则,GUI(在您的情况下是上下文菜单)会冻结,因为耗时的任务是在 UI 线程上执行的。要解决此问题,例如您可以使用BackgroundWorker

在这里,我为您提供了一个完整的工作示例,说明您可以如何做到这一点:

XAML:

<Window x:Class="WpfApplication27.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:tb="http://www.hardcodet.net/taskbar"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <tb:TaskbarIcon Name="Tray" IconSource="ico.ico" ToolTipText="text" Visibility="Visible">
            <tb:TaskbarIcon.ContextMenu>
                <ContextMenu Name="ContextMenu">
                    <MenuItem x:Name="GetPoints" Click="Run_Click" Header="points"></MenuItem>
                </ContextMenu>
            </tb:TaskbarIcon.ContextMenu>
        </tb:TaskbarIcon>
    </Grid>
</Window>

代码隐藏:

public partial class MainWindow : Window
{
    private readonly BackgroundWorker _worker;
    public MainWindow()
    {
        InitializeComponent();
        _worker = new BackgroundWorker();
        _worker.DoWork += worker_DoWork;
    }

    private void Run_Click(object sender, RoutedEventArgs e)
    {   
        _worker.RunWorkerAsync();
    }
    private void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        //here is your time consuming task 
        for (int i = 0; i < 5000; i++)
        {
            Console.WriteLine(i + "Hello World");
        }
    }
}