2013-08-26 42 views
2

我有一個ComboBox,它綁定了一個ObservableCollection並將其SelectedItem屬性綁定到T的屬性。兩個屬性均位於我的視圖模型上。一切都很好,除了一個導致我把頭髮弄掉的問題。當我在綁定到SelectedItem的對象上設置屬性時,ComboBox綁定停止工作。 VS 2012輸出窗口不會報告任何綁定錯誤,也不會引發異常。ComboBox綁定對SelectedItem中的對象進行的更改

XAML

<ComboBox ItemSource="{Binding Path=Connections, Mode=OneWay}" 
      SelectedItem="{Binding Path=SelectedConnection, Mode=TwoWay}" 
      DisplayMemberPath="Name"/> 
<TextBlock Text="{Binding Path=ConnectionName, Mode=TwoWay}" /> 
<TextBlock Text="{Binding Path=ConnectionGroup, Mode=TwoWay}" /> 

視圖模型

private void SaveChanges() 
{ 
    this.SelectedConnection.Name = this.ConnectionName; 
    this.SelectedConnection.Group = this.ConnectionGroup; 

    // -- Save the changes 
} 

現在所有的作品就好了。但是一旦SaveChanges()完成,ComboBox開始變得有趣。它看起來像一切都很好,但如果你試圖改變選擇什麼都沒有發生;選擇相同的項目並且「SelectedConnection」的設置者不會觸發。我試着系統地註釋掉SaveChanges()中的代碼,如果我只留下一行設置SelectedConnection上的任何屬性,我就會看到發生這種故障。

我還在控件背後的代碼中添加了一個事件處理程序來處理ComboBox上的SelectionChanged事件。休息發生後,任何時候我嘗試通過UI更改值或在代碼中,事件處理程序立即連續觸發兩次。第一個事件args的AddedItems設置了一個單值,這是我剛剛選擇和期望的值。然而,事件立即再次觸發,事件參數的RemovedItems集合中只有一個項目。該集合還包含我剛選擇的項目。

我已經嘗試將SelectedConnection屬性設置爲null,然後在方法結束後設置回有問題的對象。沒有運氣。

我也看到了一箇舊的錯誤帖子,關於在我的XAML標記的SelectedItem屬性後移動ItemSource屬性,但也沒有任何效果。

我試圖避免創建一個陰影列表,並試圖保持一切同步,因爲這將是我的下一個嘗試,但這只是越來越難做到這麼簡單。任何想法將不勝感激。

如果重要,這是Visual Studio 2012構建到4.5框架。

編輯

我現在也嘗試只是完全設置其屬性之後從該的ObservableCollection修改的對象。它仍然顯示爲選定的值(其名稱在ComboBox中立即可見),但不再顯示在下拉列表中。即使它不再存在於ItemSource中,它也不會允許自己被「取消選擇」。

**更新**

我的問題改變了方法完全空出,一旦過程結束與被綁定到的ItemSource,然後恢復的ObservableCollection像這樣:

private void SaveChanges() 
{ 
    var selected = this.SelectedConnection; 

    var name = this.ConnectionName; // -- bound to fields on the view 
    var group = this.ConnectionGroup; 

    this.Connections = null; 
    this.RaisePropertyChanged("Connections"); // -- SelectionChanged fires as expected 

    selected.Name = name; 
    selected.Group = group; 

    this._repository.SaveChanges(); 

    this.Connections = new ObservableCollection<Connection>(this._repository.AllConnections); 
    this.RaisePropertyChanged("Connections"); // -- SelectionChanged event doesn't fire 
    this.SelectedConnection = selected; // -- SelectionChanged event doesn't fire 
} 

完成之後,ComboBox再次允許我按照預期更改值。但是,所選項目實際上並未顯示爲選定項目(即使它已在視圖模型中正確設置)。所以是的,這是一個非常醜陋的解決方法,它也創建了自己的問題。

+1

由於您正在使用帶有複雜類型的'SelectedItem',因此應確保重寫'Equals()',以便選擇_same_對象。 – Shoe

+0

謝謝,吉姆。我以前曾經等過,但沒有變化。 – Chris

+0

奇怪的是,我無法用簡單的模型複製問題,當您保存時是否有任何事情發生在集合本身? – Chris

回答

0

我放棄了按照我最初設想的方式去做。我沒有直接修改ItemSource集合中的對象,而是使ItemSource集合成爲鍵/值對列表,並根據所選對的關鍵字從源列表中提取所需的對象。我能夠沒有問題地編輯該對象(如預期的那樣)。它現在起作用,我只是在那裏添加了一層我希望避免的代碼。用戶界面還允許我更新值對的值,以反映底層模型的「名稱」字段的更改,而不會給我以前的相同問題。我會把它算作一場小勝,然後繼續前進。

1

剛剛有這個相同的問題,我想我跟蹤了正在做的事情。

它只是在我做了一些最近的更改(由代碼分析建議)爲IComparable類添加equals/hashcode /運算符重載並在ObservableCollection中用於組合框之後纔出現。我根據對象的描述字段創建了散列碼。然而,該字段可能是用戶修改的,並且在用戶修改該值之後,組合框破裂,無法取消選擇該項目。

鑑於此對象中沒有不變的字段,因此無法根據對象的屬性創建固定的哈希代碼。但是,如果我完全刪除hashcode覆蓋(或將其設置爲固定的東西,比如type.GetHashCode),則所有事情都可以再次運行。

因此,檢查您的哈希碼是否基於您正在更改的任何值。

相關問題