#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 я использую вторую команду ICommandShowWindowsCommand
. Итак, у меня есть две ICommands. Первый вызывается по кнопке, как вы указали в своем ответе. Но вторая команда ICommand вызывается только из NotifyIcon. Также я должен напомнить вам, что у меня есть приложение WPF, а не WinForm4. Вы можете привязать свойство Command кнопки, потому что это свойство DependencyProperty . NotifyIcon — это элемент управления WinForm, поэтому у него его нет. Независимо от того, используете ли вы его в приложении WinForm или WPF, это ничего не меняет. Поскольку это элемент управления WinForm, вы должны зарегистрировать обратный вызов события в представлении и реализовать метод, который будет вызывать команду в viewmodel.
5. Вы просто регистрируете новый метод в событии с помощью
=
operator ; см. раздел редактирование