2016-05-19 39 views
0

我創建了一個應用程序,它需要大量的訪問到UI控件,現在我所做的,首先是創建一個接口可擴展性,特別是我創建了不同的控件UserControl和一個更新的用戶界面視圖模型類ViewModel是管理這個控制更新UI的所有方法。其實所有的Main線程工作良好。特別是跟隨着情景工作完美:不能在其他類

主窗口XAML

xmlns:MyControls="clr-namespace:HeavyAPP" 
... 
<!-- I use the control in the following way: --> 
<Grid> 
    <MyControls:Scheduler x:Name="Sc"/> 
</Grid> 

所以例如Scheduler控制包含此Data Binding

<StackPanel Orientation="Horizontal"> 
    <Label x:Name="NextSync" Content="{Binding NextSynchronization, IsAsync=True}" ></Label> 
</StackPanel> 

視圖模型結構

public class ViewModelClass : INotifyPropertyChanged 
{ 
    private CScheduler scheduler; 

    public ViewModelClass() 
    { 
     scheduler = new Scheduler(); 
    } 

    public string NextSynchronization 
    { 
     get 
     { 
      return scheduler.GetNextSync(); 
     } 
    } 
} 

如何在ViewModel中看到我有一個Scheduler控件的實例和一個property調用NextSyncrhonization作爲binding,所以此屬性返回控件實例的方法的結果。

對於在MainWindow使用這個我做了以下內容:

public MainWindow() 
{ 
    ViewModelClass viewModel = new ViewModelClass(); 
    DataContext = viewModel; 
} 

這個自動填充控件的屬性。現在的問題是,我使用BackgroundWorker用於執行一些任務,我需要的是使用的MainWindowDataContext不同類別,(沒有窗戶,但班)。

爲了解決這個情況我雖然做這樣的事情:

MainWindow.AppWindow.Sc.SyncLog.Dispatcher.Invoke(
      new Action(() => 
      { 
       ViewModelClass viewModel = new ViewModelClass(); 
       var dataContext = System.Windows.Application.Current.MainWindow.DataContext; 
       dataContext = viewModel; 
       viewModel.SynchronizationLog = "this is a test from other thread"})); 

現在SynchronizationLog是文本追加到控制他人財產,只是爲了精確,是這樣的:

private string _text; 
public string SynchronizationLog 
{ 
     get 
     { 
      return _text += _text; 
     } 
     set 
     { 
      _text = value; 
      OnPropertyChanged(); 
     } 
} 

這是執行INotifyPropertyChanged:

`public event PropertyChangedEventHandler PropertyChanged; 

protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
{ 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
}` 

這只是在MainWindow工作,但在外部類,我不能更新UI,我究竟做錯了什麼?

我reiceve沒有錯誤,反正。

回答

1

嘗試以下操作:

擴展您的視圖模型如下:

public class ViewModelClass : INotifyPropertyChanged 
{ 
    private CScheduler scheduler; 
    //Add this: 
    public static ViewModelClass Instance {get; set;} //NEW 
    public ViewModelClass() 
    { 
     scheduler = new Scheduler(); 
    } 

    public string NextSynchronization 
    { 
     get 
     { 
      return scheduler.GetNextSync(); 
     } 
    } 
} 

這改變了你的代碼在XAML。CS到:

public MainWindow() 
{ 
    ViewModelClass.Instance = new ViewModelClass(); 
    DataContext = viewModel.Instance; 
} 

在外部的代碼,你再DONT創建ViewModelClass的一個新的實例 - 而不是使用現有的:

[...].Dispatcher.Invoke(() => 
     { 
      if(ViewModelClass.Instance != null) 
      { 
       //Why you need the "var datacontext" in your example here ? 
       ViewModelClass.Instance.SynchronizationLog = "this is a test from other thread" 
      } 
     })); 

基本上,你在這裏做什麼是設置在屬性您來自您的viewModel之外的ViewModel。這可以從任何地方完成。

什麼是你的方法不同:

  1. 我們不創建視圖模型的一個新實例(在UI不同的綁定不再被重置了)
  2. 我們創建了一個Instance所以不可能始終只有一個視圖模型在同一時間
+0

聽起來不錯,但是這裏有一個問題:'ViewModelClass.Instance =新ViewModelClass();'你用'viewModel'變量,但沒有聲明 – Dillinger

+0

使用ClassName,因爲這是一個靜態屬性,它應該工作=>'ViewModelClass.Instance' –

+0

ClassName?你什麼意思? – Dillinger