當我使用NotifyIcon時,似乎無法在我的ViewModel中使用我的XAML代碼成功運行方法。該方法正確執行,如使用斷點的調試模式進行測試,但View中沒有任何反應。C#MVVM使用NotifyIcon從代碼隱藏中調用ViewModel方法
有問題的方法是RefreshData,它可以從視圖中的按鈕(按預期工作)或右鍵單擊NotifyIcon並選擇刷新數據(不執行任何操作)來調用。我將在下面發佈相關代碼。任何幫助,將不勝感激!在代碼隱藏
主窗口構造
public MainWindow()
{
try
{
MM = new MMViewModel();
InitializeComponent();
DataContext = MM;
_notifyIcon = new NotifyIcon();
_notifyIcon.DoubleClick += (s, args) => ShowMainWindow(this);
_notifyIcon.Icon = Migration_Monitor_v2.Properties.Resources.mmc;
_notifyIcon.Visible = true;
Closing += MainWindow_Closing;
CreateContextMenu();
}
catch (Exception e)
{
logger.Error("App failed with exception: ", e);
}
}
private void CreateContextMenu()
{
_notifyIcon.ContextMenuStrip = new ContextMenuStrip();
_notifyIcon.ContextMenuStrip.Items.Add("Refresh Data").Click += (s,e) => MM.RefreshData();
_notifyIcon.ContextMenuStrip.Items.Add("Exit").Click += (s, e) => ExitApplication(this);
}
RefreshData方法在視圖模型
public void RefreshData()
{
InfoPanelVisible = Visibility.Hidden;
InfoSummaryVisible = Visibility.Visible;
Task.Run(() => LoadData());
n = DateTime.Now;
ProgressBarText = "Click a project to show progress";
ProgressBarValue = 0;
lastRefresh.Reset();
lastRefresh.Start();
}
稱爲LoadData方法(和相關方法)從RefreshData
(來自刷新按鈕在View執行時作品)public async void LoadData()
{
IsLoading = Visibility.Visible;
await GetWebApiInfo();
MonitorData downloadInfo = main;
try { AssignDataToControls(downloadInfo); }
catch (Exception e) { Console.WriteLine("Error: " + e); }
finally { IsLoading = Visibility.Hidden; }
}
public void AssignDataToControls(MonitorData mon)
{
MainPanel.Clear();
MonitorText.Clear();
mon.MainPanel.ToList().ForEach(x => MainPanel.Add(x));
mon.MonitorText.ToList().ForEach(x => MonitorText.Add(x));
Information = mon.Information;
ProgressData = mon.progList;
}
public async Task GetWebApiInfo()
{
var url = "::::WEB API ADDRESS::::";
string responseFromServer;
using (HttpClient _client = new HttpClient())
using (var dataStream = await _client.GetStreamAsync(url))
using (var reader = new StreamReader(dataStream, Encoding.Unicode))
responseFromServer = await reader.ReadToEndAsync();
var deserializer = new JavaScriptSerializer();
main = deserializer.Deserialize<MonitorData>(responseFromServer);
}
RefreshCommand from ViewModel Commands.cs fil e
internal class RefreshCommand : ICommand
{
public RefreshCommand(MMViewModel viewModel)
{
_viewModel = viewModel;
}
private MMViewModel _viewModel;
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return _viewModel.CanRefresh;
}
public void Execute(object parameter)
{
_viewModel.RefreshData();
}
}
沒有東西在我身上彈出。你聲稱「該方法正確執行」,但不清楚你在說什麼方法。例如,如果你想在每個方法的開始處放置斷點,那麼點擊通知圖標,你實際設法走多遠的調用堆棧?您可以將一個Action添加到斷點,以便只打印剛剛在調試控制檯中執行的方法的名稱,這很方便。 – Will
接下來,我會檢查視圖模型是您認爲它是什麼的假設。在LoadData方法中放置一個斷點。從任務欄觸發它,當它被命中時,將一個對象ID分配給'this'(如果你不知道對象ID如何工作,則搜索該術語)。接下來,從窗口中觸發它。當命中斷點時,檢查'this'來查看它是否有對象ID。如果沒有,你的數據上下文正在改變。 – Will
對於CompositeCommand來說,這看起來像是一份工作。這是一個「shell」命令,允許各種虛擬機訂閱它以處理CanExecute/Execute。 – SledgeHammer