2012-03-01 47 views
4

我有一個看似簡單的任務,這是讓我頭痛,並希望得到一些幫助。綁定問題與RadioButton

我想完成的是將兩個布爾值綁定到兩個RadioButton的IsChecked屬性,共享相同的GroupName(因此一次只檢查一個)。

我面臨的問題是,當ContentPresenter的內容即將更改(通過綁定到ComboBox的SelectedItem)時,當前內容會接收對具有相同屬性值的Property-setter的調用而是從即將成爲新內容的視圖模型。 (!)最終的結果是儘管沒有點擊與有問題的屬性綁定的RadioButton,但視圖模型發生了變化。

我已經把together a sample app顯示出這個問題。要重現,運行應用程序,並按照下列步驟操作:在下拉列表

  1. 選擇「一」 => MyPropery檢查,MyProperty2不是。
  2. 在combobox中選擇「Three」=>選中MyPropery,MyProperty2不是。
  3. 雖然仍然選擇「三」,單擊MyProperty2 => MyProperty2選中(也顯示在調試輸出窗口中)
  4. 選擇「One」在combobox => MyPropery被選中,MyProperty2不是。 請注意調試窗口如何顯示對象「Three」的MyProperty2如何設置爲false
  5. 在組合框中選擇「Three」=>現在選中兩個Radiobutton(由於#4)。

如果在#3和#4之間,首先在組合框中選擇「Two」以使ContentPresenter顯示另一個視圖(通過DataTemplate選擇),則問題不會出現!

有人可以解釋爲什麼在ContentPresenter交換視圖時爲什麼該屬性設置爲步驟#4,並且可以做些什麼?

回答

1

數據模板被高速緩存,所以OneThree使用完全相同UserControl。您可以通過向控件添加Loaded事件並在選項之間切換來驗證此情況。

當您切換到Two和回Three,WPF將簡單地重新繪製從緩存中的項目,但是切換到One和回Three,它改變了對象後面的DataContext。我認爲這是造成這個問題,因爲它似乎是在刪除DataContext之前清除第二個RadioButton IsChecked,所以最終結果是Property2被設置爲false。如果OneThree都選擇了第二個單選按鈕,則不會發生這種情況。

通常在這種情況下,我會讓虛擬機包含一個ObservableCollection<T> Items和一個int SelectedIndex。然後,我將使用已被覆蓋的ListBox來繪製UI,以便使用RadioButton作爲項目。這樣一次只能選擇一個項目,並且只有一個屬性用於存儲所選項目。

+0

+1。 Rachels絕對正確:緩存DataTemplate生成的UIElements,並且UI中的CheckBox分組被激活到ViewModel中,從而搞亂了複選框的狀態。 – SvenG 2012-03-01 15:35:57

+0

所以基本上,GroupName和MVVM/DataTemplates不會混合。 :(我無法使用ListBox解決方案,因爲我必須將RadioButton分開放置,我想我必須使用常規復選框,而不是在虛擬機中處理組合。感謝您的幫助。 – Per 2012-03-01 16:01:37

0

它似乎是一個錯誤(ContentPresenter的內容發生了變化,但DataContext沒有)。

但我可以爲您提供解決方案。在您的例子做以下(MainWindow.xaml):

<StackPanel> 
    <ComboBox ItemsSource="{Binding MyItems, Mode=OneWay}" Name="cmbBox" DisplayMemberPath="ID" SelectionChanged="cmbBox_SelectionChanged"/> 
    <ContentPresenter Name="cp1" /> 
</StackPanel> 

在cmbBox_SelectionChanged看起來如下:

private void cmbBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    cp1.Content = null; 
    cp1.DataContext = null; 
    cp1.Content = cmbBox.SelectedItem; 
} 

這解決了這個問題(沒有很好的解決方案,但有解決方法)。