2016-12-02 9 views
1

NotifyIconを使用しているときに、私のViewModelでXAMLコードのメソッドを正常に実行できないようです。このメソッドは、ブレークポイントを使用してデバッグモードでテストされたとおり正しく実行されますが、ビューでは何も起こりません。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(); 
    } 

refreshdataを

から呼び出さloaddataの方法(及び関連する方法)
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); 
    } 

ViewModelからのRefreshCommand 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(); 
    } 
} 
+0

私には何も出ません。あなたは「このメソッドは正しく実行されます」と主張しますが、あなたが話している方法が明確ではありません。たとえば、各メソッドの開始時にブレークポイントを配置する場合は、通知アイコンをクリックします。コールスタックの実際の移動距離はどれくらいですか?ブレークポイントにアクションを追加すると、デバッグコンソールで実行されたばかりのメソッドの名前が表示されるだけで便利です。 – Will

+0

次に、ビューモデルがあなたの考えであると仮定していることを確認します。 LoadDataメソッドにブレークポイントを設定します。それをタスクバーからトリガし、ヒットしたらオブジェクトIDを 'this'に代入します(オブジェクトIDの仕組みがわからない場合は検索します)。次に、ウィンドウからトリガします。ブレークポイントがヒットしたら、 'this'をチェックしてオブジェクトIDを持っているかどうかを調べます。そうでない場合は、データコンテキストが何らかの形で変更されています。 – Will

+0

私にはCompositeCommandの仕事のようです。これは、さまざまなVMがCanExecute/Executeを処理するためにそれを購読できるようにする「シェル」コマンドです。 – SledgeHammer

答えて

0

この問題を解決しました。問題は、私のViewModelが3回別々に構築されていたため、どのインスタンスが参照されているかは不明です。

これを修正するために、私はXAMLウィンドウ定義空間でViewModelへの参照を削除しました。 ViewModelにローカル名前空間(x:local.VM = "MM.MyViewModel")として必要と思われる2つの参照がありました。これらを削除すると、ViewModelは一度しか構築されず、すべてのコードが意図したとおりに実行されます。彼の助けがこの一番下に来てくれたので、@ウィルに感謝します!

関連する問題