2011-05-10 83 views
2

我有一個奇怪的行爲,當我關聯和組合框到我的viewmodel。行爲如下,當我更改組合的選定值時,我對新值進行驗證,如果這個新值無效,我保留舊值並丟棄新值,這樣我就不會提高Inotifypropertychanged,但是與組合框關聯的屬性的getter無論如何都是調用的,這會得到我想要顯示的舊值,但是組合框顯示新值,即使組合框的選定值爲舊且正確的值,我檢查了調試模式。我不知道我該如何解決這個問題,因爲我從未見過這種行爲,任何建議都將不勝感激。WPF ComboBox MVVM奇怪的行爲

這是對XAML

<ComboBox Height="23" Name="cbxStatus" HorizontalAlignment="Left" 
      ItemsSource="{Binding Path=Status, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" 
      SelectedItem="{Binding Path=SelectedStatus, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 
      DisplayMemberPath="Value" Width="130" VerticalAlignment="Center" 
      IsEnabled="{Binding Path=StatusEnable, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 

的代碼是這樣的視圖模型代碼,物業

public Config SelectedStatus 
{ 
    get 
    { 
     if (ApplicationAction == ApplicationAction.Add) 
     { 
      base.Object.State = configManager.BudgetInitStatus(); 
      StatusEnable = false; 
     } 
     else 
     { 
      StatusEnable = true; 
     } 
     return base.Object.State; 
    } 
    set 
    { 
     if (base.Service.CanChangeBudgetStatus(base.Object, value)) 
     { 
      base.Object.State = value; 
      base.Object.IsDirty = true; 
     } 
     RaiseOnPropertyChanged("SelectedStatus"); 
     RaiseOnPropertyChanged("AssociateOrderButtonVisibility"); 
    } 
} 

感謝您的幫助

回答

2

設置您的結合

IsAsync=True 

會工作。

+0

你好,謝謝你的答案,我嘗試了兩種可能性,並結合了兩者,但在我的情況下,這是一個工作,雖然我認爲這兩個都有點哈克,我不明白爲什麼這個工作,因爲從什麼我在msdn中讀到它只是爲了在綁定過程中稍後獲得一個屬性,可以這麼說。我認爲組合框應該「足夠聰明」,以便在「selected」屬性被「通知」時顯示該值,而不是之前選擇的值。但那是我的看法。再次感謝您的幫助 – 2011-05-11 10:51:29

0

當用戶在組合框中更改數值,它會在組合框中發生變化,與您的視圖模型無關。

如果您更改該值並且不會引發屬性更改通知,那麼您的視圖模型和視圖將不同步。

總之,當您拒絕選定的值時,您仍然需要屬性更改通知。

+1

即使更改通知(他有)WPF將忽略更改,因爲它*期望*在該時間點的更改通知。不期望的是價值不是它提供給財產創造者的東西。 – 2011-05-10 17:36:02

+0

好吧,先生。 – Jay 2011-05-10 20:16:37

4

正如我在Jay給我的評論中指出的那樣,這裏的問題在於WPF正在設置該值,而不是聽取您的更改通知(畢竟期待它)。您需要做的是在當前消息的上下文之外引發屬性更改通知。你可以做到這一點使用的調度程序,例如:

set 
{ 
    if (!valid) 
    { 
     // value is unchanged 
     Dispatcher.BeginInvoke(delegate { this.OnPropertyChanged(...) }); 
     return; 
    } 

    // value is changed here 
} 

這將確保執行綁定消息當前數據,然後單獨的消息告訴WPF說,「其實,你只是提供給我的二傳手值不更長的當前值「。

如果您願意,也可以使用SynchronizationContext。無論哪種方式,我承認這有點冒險。不幸的是,我不知道這個方法。事實是,WPF假定它傳遞給你的setter的價值是財產的有效價值。否則,在綁定操作的上下文中沒有任何屬性更改通知會說服它。

+0

+1。一定會記得的。 – Willem 2011-05-10 17:49:12

+0

肯特,你會說使用'Async = True'完成這個的潛在缺點嗎? – Jay 2011-05-11 01:47:18