2011-05-11 47 views
1

我有一個ComboBox,它的Items屬性綁定到一組對象。我還將SelectedItem屬性綁定到整個集合,其中ValueConverter設計用於檢查集合中的元素並返回要選擇的1個項目。這部分工作。讓'ConvertBack(...)'在WPF組合框選擇更改上觸發

不起作用的是當用戶在組合框上進行選擇更改時,ValueConverterConvertBack(...)方法未被調用。我需要調用ConvertBack(...),因爲我需要接受用戶的選擇,重新檢查集合,並適當地編輯舊選定項目和新選定項目。

我知道這種方法是一個尷尬,但它是這樣的。下面是相關的代碼:

組合框:

<ComboBox ItemsSource="{Binding}" SelectedItem="{Binding Path=., Converter={StaticResource ResourceKey=DataInputAssetChoiceSelectedItemConverter}}" /> 

ValueConverter:

public class DataInputAssetChoiceSelectedItemConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value != null) 
     { 
      foreach (CustomObject Choice in (Collection<CustomObject>)value) 
      { 
       if (Choice.IsSelected) 
       { 
        return Choice; 
       } 
      } 
      return ((Collection<CustomObject>)value).First(); 
     } 
     return null; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { //breakpoint...execution never gets here! 
     return null; 
    } 
} 

那麼,爲什麼不ConvertBack(...)曾經被調用?這只是我誤解ComboBox?我試過這種方法,使用SelectedItem,SelectedValue,SelectedIndex,並試圖搞亂UpdateSourceTrigger,各種綁定模式,DataTriggers,並且永遠不會得到ConvertBack(...)被調用。正在使用SelectionChanged事件的唯一選項?如果是這樣,爲什麼?

回答

3

你沒有綁定到一個屬性,所以綁定不能設置任何東西。您直接綁定到DataContext對象,並且綁定不會更新它。

如果您有{Binding Path=SomeProperty, Converter=...}那麼將調用ConvertBack。儘管如此,它不會被調用。

+0

感謝您的這個珍聞。基於這種行爲,可能使用DataContext作爲綁定的源代碼應該被禁止,因爲它無法完全參與綁定。我想我必須使用SelectionChanged事件並從那裏編輯DataCollection的內容。要麼或更改數據模型,以便我可以綁定到一個實際的屬性......但這將是可怕的。 – tyriker 2011-05-11 18:24:59

+0

標記爲答案,因爲你解釋了爲什麼ConvertBack(...)不適用於這種特殊情況。謝謝。 – tyriker 2011-05-11 19:24:47

2

你是對的,這很尷尬,但僅僅是因爲你試圖在集合中添加一些管理而不是集合本身。我認爲,這將有助於如果您的收藏更清楚其項目有一個IsSelected屬性:

public CustomCollection : Collection<CustomObject> { 
    CustomObject _current; 
    public CustomObject CurrentSelection { 
     get { return _current; } 
     set { 
      if (_current == value) 
       return; 

      if (_current != null) 
       _current.IsSelected = false; 

      if (value != null) 
       value.IsSelected = true; 

      _current = value; 
     } 
    } 
} 

只需添加一點點額外的,以確保_current至少集合中的第一個元素。

<ComboBox ItemsSource="{Binding}" SelectedItem="{Binding CurrentSelection}"> 

現在你不應該需要轉換器了。但是有一些考慮因素缺失。您可能希望使用ObservableCollection<T>,並在CurrentSelection發生更改時引發PropertyChanged事件,以便如果有其​​他任何內容綁定到該屬性,或者在代碼中進行了更改,則所有綁定都會進行適當更新。

編輯:包裝紙模型

一個簡單的方法來包裝集合,而不是做一個自定義集合像上面:

public class CollectionWrapper : INotifyPropertyChanged { 
    public event PropertyChangedEventHandler PropertyChanged = (o,e)=>{}; 
    // never have to check for null 

    public CollectionWrapper(Collection<CustomObject> collection) { 
     Items = collection; 
    } 

    // unlikely to change, so let's prevent it for now 
    public Collection<CustomObject> Items { 
     get; 
     private set; 
    } 

    CustomObject _current; 
    public CustomObject CurrentSelection { 
     get { return _current; } 
     set { 
      if (_current == value) 
       return; 

      if (_current != null) 
       _current.IsSelected = false; 

      if (value != null) 
       value.IsSelected = true; 

      _current = value; 
      PropertyChanged(this, new PropertyChangedEventArgs("CurrentSelection")); 
     } 
    } 
} 

那麼這個對象成爲你的數據上下文和ComboBox綁定變化到這:

<ComboBox ItemsSource="{Binding Items}" SelectedItem="{Binding CurrentSelection}"> 
+0

是的,改變數據模型可能是最好的解決方案,但在目前的情況下並不容易。也許我會爲這個特定綁定的集合製作一個多餘的「包裝器」類。 – tyriker 2011-05-11 19:22:50

相關問題