2011-10-31 30 views
0

我有一個後臺工作進程爲我們的系統開始配置新客戶端。這裏是DoWork的方法是什麼樣子:綁定按鈕在後臺工作進程完成後未啓用

ProvisioningManager manager = new ProvisioningManager(false) 
{ 
}; 

System.Windows.Application.Current.Dispatcher.Invoke((Action)(() => 
{ 
    this.MaxSteps = manager.MaxProgress; 
})); 

manager.StatusUpdated += new ProvisioningManager.StatusUpdatedHandler(manager_StatusUpdated); 
manager.TaskCompleted += new ProvisioningManager.TaskCompleteHandler(manager_TaskCompleted); 

manager.ProvisionClient(); 
while (!manager.Completed) 
{ 
    System.Threading.Thread.Sleep(100 * 60); 
} 

基本上,它會創建一個處理聊到不同的子系統,其提供的客戶經理。

現在我有一個狀態更新事件和已完成的供應管理器事件。當TaskCompleted事件觸發我希望能夠把我的顯示對象的屬性,以便在嚮導中完成按鈕啓用:

void manager_TaskCompleted(object sender, ProvisioningManager.Task taskType) 
{ 
    System.Windows.Application.Current.Dispatcher.Invoke((Action)(() => 
    { 
     this.ProvisioningComplete = true; 
    })); 
} 

該按鈕的XAML看起來是這樣的:

<wizard:WizardPage Header="Provisioning Client..." 
           ShowBack="False" 
           AllowBack="False" 
           AllowFinish="{Binding Source={StaticResource ResourceKey=dataObject}, Path=ProvisioningComplete}" 
           Loaded="Provisioning_Loaded"> 
</wizard:WizardPage> 

這不起作用。即使我確保點擊調度程序線程來設置顯示對象的屬性,但它實際上並不會將該按鈕更改爲啓用,直到我單擊該窗口。這是AvalonWizard中的錯誤還是我沒有在正確的線程上設置INotifyPropertyChanged?有沒有辦法破解這個;基本上我可以在沒有鼠標點擊的情況下以編程方式聚焦窗口

我累了配售,雖然環在DoWork的方法,這樣我可以使用的BackgroundWorker的完成方法:

void provisioningWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    System.Windows.Application.Current.Dispatcher.Invoke((Action)(() => 
    { 
     this.ProvisioningComplete = true; 
    })); 
} 

,不能正常工作。是什麼賦予了?!

更新 這裏是顯示對象所要求的靜態資源實例:

<Window.Resources> 
    <ObjectDataProvider x:Key="dataObject" ObjectType="{x:Type winDO:NewClientWizardDO}" /> 
</Window.Resources> 

更新II 這裏是屬性和屬性修改射手:

public bool ProvisioningComplete 
{ 
    get { return this._ProvisioningComplete; } 
    set 
    { 
     this._ProvisioningComplete = value; 
     this.NotifyPropertyChanged("ProvisioningComplete"); 
    } 
} 

protected void NotifyPropertyChanged(params string[] propertyNames) 
{ 
    if (this.PropertyChanged != null) 
    { 
     foreach (string propertyName in propertyNames) 
      this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 
+0

你可以請你的靜態資源的聲明「StaticResource ResourceKey = dataObject」? – Murven

+0

@Murven,請求的代碼已被添加到問題中。感謝您查看此問題。 –

+0

我假設NewClientWizardDO實現INotifyPropertyChanged並且屬性ProvisioningComplete觸發PropertyChangedEvent。您能否確認或發佈該課程的代碼?我很抱歉,我也應該要求提供這一個,不確定這一點很難說清楚。 – Murven

回答

0

所以我找不到到底爲什麼我有這個問題。我嘗試將焦點設置到窗口,按鈕等。我嘗試了多種方法讓視圖知道視圖模型已更新。基本上我在網上找到的每一個建議都不起作用。它幾乎看起來像一個錯誤。

我的團隊中聰明的人建議在窗口上點擊鼠標。他的想法是,因爲激活按鈕所需要的只是一個簡單的鼠標點擊屏幕,然後僞造一個應該有同樣的效果。我認爲(並認爲)這種黑客太荒謬了。我確實嘗試過,看看我能否稱之爲「解決方案」。

好,它的工作。我們在嚮導(不AvalonWizard但自產自銷)的另一個有同樣的問題。我認爲必須有與被綁定到UI後臺線程更新對象後窗口重繪方式的一些潛在的問題。

無論如何,我發現瞭解決這個問題的方法是使用下面的技巧,tastic代碼。

//import user32.dll and setup the use of the mouse_event method 
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 

/// <summary> 
/// Watches for properties to change on the data object, mainly the ProvisioningComplete method 
/// </summary> 
/// <param name="sender"></param> 
/// <param name="e"></param> 
void DataObject_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) 
{ 
    switch (e.PropertyName) 
    { 
     case "ProvisioningComplete": 
      //if the provisioning is completed then we need to make the finish button selectable. 
      if (this.DataObject.ProvisioningComplete) 
      { 
       System.Windows.Application.Current.Dispatcher.Invoke((Action)(() => 
       { 
        //give the window focus 
        this.Focus(); 
        //update the layout 
        WizardPageProvisioningClient.UpdateLayout(); 
        //fake mouse click 50 pixels into the window 
        mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, (uint)(this.Left + 50), (uint)(this.Top + 50), 0, 0); 
       })); 
      } 
      break; 
    } 
} 

我測試過,當窗口不是活動窗口,當用戶離開窗口選定。當窗口不活動時,焦點方法似乎處理這個問題。我們的QA團隊沒有針對UI進行完整的測試,所以我不能說是否有什麼情況不起作用,但似乎是我迄今爲止提出的最佳解決方案。

我願意接受任何其他建議,如果有人有更好的主意,可能會導致按鈕不更新。

0

對不起,如果我不明白,但ProvisioningComplete屬性標記爲「volatile」?如果不是,那麼這可能是問題所在。

+0

我不確定你的意思是標記不穩定的東西。這是一個綁定標記或屬性的屬性? –

+0

有一個例子和簡短的解釋http://msdn.microsoft.com/it-it/library/x13ttww7(v=vs.80).aspx –

+0

這似乎是有道理的,但唉,沒有用戶活動的即使將volatile關鍵字添加到屬性後面的字段後,該按鈕也不會將狀態從禁用狀態更改爲啓用狀態。我開始認爲它可能是一個AvalonWizard錯誤。 –

相關問題