Вызов команды ICommand из Windows.Формы.Событие NotifyIcon .Щелчок мышью() [Приложение WPF]

#c# #wpf

#c# #wpf

Вопрос:

Я создал пользовательский NotifyIcon объект, унаследованный от оконных форм. Просматривая свойства и методы класса NotifyIcon здесь, я увидел, что я могу вызвать событие, когда пользователь нажимает на NotifyIcon на панели задач. Итак, я создал следующий код внутри ViewModel

 namespace TestEnvironment
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public ICommand ShowWindowsCommand //this is the ICommand I want to call in .MouseClick()
        {
            get { return new DelegateCommand<object>(FunctionShowWindows); }
        }
        private void FunctionShowWindows(object parameter)
        {
            ProgressBarTemplate ProgressBarInstance = (ProgressBarTemplate)Application.Current.Windows.OfType<Window>().SingleOrDefault(window => window.Name == "ProgressBarScreen");
            if (ProgressBarInstance != null)
            {
                if (MainWindowInstance.MaxHeight > 725 amp; MainWindowInstance.MaxWidth > 1200)
                {
                    MainWindowInstance.WindowState = WindowState.Maximized;
                    MainWindowInstance.Activate();
                    //MainWindowInstance.Topmost = true;
                }
                else
                {
                    MainWindowInstance.WindowState = WindowState.Normal;
                    MainWindowInstance.Activate();
                    //MainWindowInstance.Topmost = true;
                }
                ProgressBarInstance.Show();
                ProgressBarInstance.WindowState = WindowState.Normal;
                //ProgressBarInstance.Topmost = true;
            }
            else
            {
                if (MainWindowInstance.MaxHeight > 725 amp; MainWindowInstance.MaxWidth > 1200)
                {
                    MainWindowInstance.WindowState = WindowState.Maximized;
                    MainWindowInstance.Activate();
                    //MainWindowInstance.Topmost = true;
                }
                else
                {
                    MainWindowInstance.WindowState = WindowState.Normal;
                    MainWindowInstance.Activate();
                    //MainWindowInstance.Topmost = true;
                }
            }
        }

        public ICommand RunCalculationCommand_Approach2
        {
            get { return new DelegateCommand<object>(ExecuteSqlAsync); }
        }
        private async void ExecuteSqlAsync(object obj)
        {
            Stream iconStream_one = Application.GetResourceStream(new Uri("pack://application:,,,/TestApp;component/Assets/loading.ico")).Stream;
            
            System.Windows.Forms.NotifyIcon notification_object = new System.Windows.Forms.NotifyIcon
            {
                Icon = new Icon(iconStream_one),
                Visible = true
            };

            // The complete Task API accepts a CancellationToken to allow cancellation.
            try
            {
                DateTime timestamp_start = DateTime.Now;

                await Task.Run(() => RunCalculationsMethod(object_progressbar, "LOG_DETAILS", 1, true, getconnectionstring, CatchErrorExceptionMessage, this.CancellationTokenSource.Token), this.CancellationTokenSource.Token);
                
                string[] time_passed = DateTime.Now.Subtract(timestamp_start).ToString().Split(@":");

                List<SucessfulCompletion> reportsucessfulcompletion = new List<SucessfulCompletion>();
                reportsucessfulcompletion = CheckLogsFailSuccessProcedure(SQLServerConnectionDetails());

                if (reportsucessfulcompletion[0].Result == 0)
                {
                    notification_object.ShowBalloonTip(5000, "Hi", "This is a BallonTip from Windows Notification", System.Windows.Forms.ToolTipIcon.None);
                    //notification_object.MouseClick  = new System.EventHandler(ShowWindowsCommand);
                }
                else
                {
                    notification_object.ShowBalloonTip(5000, "Hi", "Hello World", System.Windows.Forms.ToolTipIcon.None);
                    //notification_object.MouseClick  = new System.EventHandler(ShowWindowsCommand);
                }
            }
            catch (Exception ex)
            {
                //..
            }
            finally
            {
                //..
            }
        }
    }
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            DataContext = new MainWindowViewModel();
            Closing  = CancelSqlOperationsOnClosing;
        }
    }
}
 

XAML

 <Window x:Class="TestEnvironment.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestEnvironment"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Button Content="Show Toast"
        Padding="10"
        HorizontalAlignment="Center"
        VerticalAlignment="Center"
        Command="{Binding RunCalculationCommand_Approach2}"/>
    </Grid>
</Window>

 

Я хочу вызвать команду ICommand ShowWindowsCommand из события MouseClick .

//notification_object.MouseClick = new System.EventHandler(ShowWindowsCommand); -> This is what I want to fix

Но это событие принимает обработчики событий. Итак, есть ли какой-либо способ вызвать команду ICommand из MouseClick события NotifyIcon ?

Ответ №1:

Поскольку NotifyIcon на самом деле это не элемент управления, который отображается на странице, вы можете создать его экземпляр в ViewModel . Для того чтобы запустить команду при нажатии на значок, вам просто нужно реализовать обратный вызов события.

MainWindowViewModel.cs

 namespace TestEnvironment
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public ICommand ShowWindowsCommand
        {
            get { return new DelegateCommand<object>(FunctionShowWindows); }
        }

        private void FunctionShowWindows(object parameter)
        {
            // redacted
        }

        public ICommand RunCalculationCommand_Approach2
        {
            get { return new DelegateCommand<object>(ExecuteSqlAsync); }
        }

        private async void ExecuteSqlAsync(object obj)
        {

            Stream iconStream_one = Application.GetResourceStream(new Uri("pack://application:,,,/TestApp;component/Assets/loading.ico")).Stream;
            
            System.Windows.Forms.NotifyIcon notification_object = new System.Windows.Forms.NotifyIcon
            {
                Icon = new Icon(iconStream_one),
                Visible = true
            };

            notification_object.MouseClick  = new System.Windows.Forms.MouseEventHandler(NotifyIcon_MouseClick);

            // redacted
        }

        private void NotifyIcon_MouseClick(object sender, EventArgs e);
        {
            FunctionShowWindows(null);
        }
    }
}
 

Комментарии:

1. Привет, ArwynFr и спасибо за ваш ответ. Основываясь на вашем ответе, я должен назначить моему нажатию кнопки свойство, с Image_Click которым все в порядке. Но откуда я знаю, что NotifyIcon также выполнит ShowWindowsCommand ICommand?

2. Вы не упомянули кнопку в своем вопросе. Для элементов управления WPF просто свяжите команду. Для NotifyIcon, поскольку это элемент управления Winforms, привязка не работает, поэтому вы используете обратный вызов. См. Редактирование ответа.

3. ArwynFr да, у меня есть кнопка. Для кнопки я привязываю команду ICommand RunCalculationCommand_Approach2 . Но для NotifyIcon я использую вторую команду ICommand ShowWindowsCommand . Итак, у меня есть две ICommands. Первый вызывается по кнопке, как вы указали в своем ответе. Но вторая команда ICommand вызывается только из NotifyIcon. Также я должен напомнить вам, что у меня есть приложение WPF, а не WinForm

4. Вы можете привязать свойство Command кнопки, потому что это свойство DependencyProperty . NotifyIcon — это элемент управления WinForm, поэтому у него его нет. Независимо от того, используете ли вы его в приложении WinForm или WPF, это ничего не меняет. Поскольку это элемент управления WinForm, вы должны зарегистрировать обратный вызов события в представлении и реализовать метод, который будет вызывать команду в viewmodel.

5. Вы просто регистрируете новый метод в событии с помощью = operator ; см. раздел редактирование