2013-07-26 129 views
1

我建立一個WPF應用程序(.NET 4.0),我有以下情況:WPF/MVVM結合複選框selectedItem屬性

<ListBox 
    ItemsSource="{Binding Path=Items}" 
    SelectedItem="{Binding Path=SelectedItem}"> 
    <ListBox.ItemContainerStyle> 
     <Style TargetType="ListBoxItem"> 
      <Setter Property="Height" Value="48"/> 
     </Style> 
    </ListBox.ItemContainerStyle> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <DockPanel> 
       <!-- ... --> 
       <CheckBox> 
        <CheckBox.IsChecked> 
         <!-- Something here that behaves like SelectedItem binding --> 
        </CheckBox.IsChecked> 
       </CheckBox> 
      </DockPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 
  • ListBox的的ItemSource勢必一個ObservableCollection <>。
  • ListBox的SelectedItem綁定到ViewModel的SelectedItem屬性 。

但是,當ViewModel.SelectedItem更新時,一小段長時間運行(2-3s)的異步任務將被啓動。 通過簡單地選擇列表框中的不同項目來排隊大量的異步任務是非常容易的,所以我正在研究將ViewModel.SelectedItem綁定到CheckBox(包含在ItemTemplate中)。

我對WPF相當陌生,但在窗體中我會附加一個事件處理程序並編寫一些冗長而難看的代碼來取消所有項目,但觸發事件的項目,然後以編程方式更新屬性。我希望有一些更好的解決方案,我已經看過使用ValueConverter,但我不知道如何綁定到父視圖模型(具有ObservableCollection <>)。

如果有人遇到過類似的要求,我真的很感激一些指針。

乾杯!

./Fredrik

+0

不會吧通過反覆點擊複選框,排隊大量異步任務同樣容易嗎?我猜你需要的是一種機制,在新的啓動時取消當前正在運行的任務。而且您可能會考慮延遲執行任務,而不是在所選項目更改時立即執行。 – Clemens

+0

嗨克萊門斯,thans響應!是的,它會,但是在異步任務運行時防止更改已選狀態應該不會太困難。我試圖在任務運行時禁用ListBox,但這太難看了。添加CheckBox的好處是ListBox中的選擇與任務分離,允許用戶在任務運行時瀏覽列表框。 – Fredrik

+0

您也可以考慮在列表框外部(而不是所有複選框)有一個專用按鈕來啓動當前選定項目上的任務。這不僅更容易實現,而且還可能導致更直觀的用戶界面。 – Clemens

回答

0

我想出了一個解決方案,它不會在代碼隱藏方面處理已檢查的狀態,所以我將爲後人記錄它。

第一個竅門是使用RadioButton代替,並與GroupName相關聯。同一組內的單選按鈕將自動確保在任何給定時間只檢查其中的一個,這可避免手動管理已檢查狀態的問題。

第二個技巧是將CommandParameter綁定到單選按鈕DataContext

<RadioButton 
    Name="rdbSelected" 
    GroupName="itemsRadioGroup" 
    Command="{Binding 
     RelativeSource={RelativeSource AncestorType=UserControl}, 
     Path=DataContext.SelectItemCommand}" 
    CommandParameter="{Binding 
     RelativeSource={RelativeSource Self}, 
     Path=DataContext}"/> 

單選按鈕指揮火災的每次點擊,不只是當它被選中,但我們擺脫這一點,因爲不像CheckBox它是不可能取消選中一個單選按鈕,這樣雙擊無線電按鈕只會確認SelecedItem

如果SelectedItem屬性觸發一個事件PropertyChanged,它可能是最好有命令處理程序檢查它是否在事實上設定了新的價值,或者只是在重複以前的一個:

RelayCommand<object> cmd = new RelayCommand<object>(
    (o) => 
    { 
     if (this.SelectedItem != o) 
      this.SelectedItem = o; 
    }); 
0

嗨可以綁定的複選框司令部VM和該命令將火的時候複選框被選中/取消。

+0

嗨,謝謝你的迴應! 現在我們關閉了。該命令讓我以編程方式設置SelectedItem,但ListBox中有多個項目,每個項目都使用CheckBox進行模板化。 我將如何取消檢查其他CheckBox,保留SelectionMode單行爲? 乾杯! – Fredrik

+0

您可以在ViewModel中取消選中它們,並且更改將反映在用戶界面 – ethicallogics

+0

就像您有布爾綁定到ISelected的那些CheckBoxes列表和當您想取消全部它們然後只設置列表中的所有值false並設置Selected Item列出true。它的一切都關於你在虛擬機中的邏輯有多好 – ethicallogics

0

您可以通過TemplateBinding將ListBoxItem的isselected屬性綁定到複選框。

+0

嗨Nakul,感謝您的迴應! 實際上這不會改變列表框選擇和檢查狀態(至少對於雙向綁定)。我的purpouse是在View-Model中有一個屬性SelectedItem反映ListBox中的哪個(單個)項目被選中。 乾杯! – Fredrik