2013-12-16 63 views
0

我有一個報告頁面,顯示我們報告的一組數據的視圖。這個視圖有大約40個字段。用戶可以查詢和過濾數據以獲得他們所需的數據,然後將其導出到Excel報告中,然後自動通過電子郵件發送給需要查看信息的管理。複選框選擇全部或全部取消選擇不受數據集綁定的列表視圖

因爲並非所有的字段都是每個報告都需要的,我也有一個列表框旁邊的複選框來隱藏或顯示任何字段。我一直在試圖找出如何通過選擇標題中的複選框來選中或取消選中所有複選框。列表框的xaml綁定到網格中字段的IsVisible屬性,看起來像這樣。

<ListView ItemsSource="{Binding Columns, ElementName=reportGrid}" SelectionMode="Multiple"> 
    <ListView.View> 
     <GridView> 
      <GridViewColumn Width="50"> 
       <GridViewColumn.HeaderTemplate> 
        <DataTemplate> 
          <CheckBox x:Name="checkall" IsChecked="{Binding IsMainSelected}" Tag="{Binding Source={StaticResource Spy}, Path=DataContext}" /> 
        </DataTemplate> 
       </GridViewColumn.HeaderTemplate>              <GridViewColumn.CellTemplate>            
        <DataTemplate > 
         <CheckBox IsChecked="{Binding IsVisible}" /> 
        </DataTemplate> 
      </GridViewColumn.CellTemplate> 
      </GridViewColumn> 
           <GridViewColumn Header="Field" DisplayMemberBinding="{Binding Header}" Width="100"></GridViewColumn> 
      </GridView> 
    </ListView.View> 

的間諜靜態資源的引用來自這篇文章。 http://www.codeproject.com/Articles/27432/Artificial-Inheritance-Contexts-in-WPF

但是,我遇到的每個解決方案的問題是這樣的事實,即listview中的複選框綁定到數據集。在這種情況下,複選框被綁定到網格中的列的可見性(在頁面上的對象上)。我嘗試過的所有東西都失敗了。這可能是一個簡單的解決方案,但如果我能弄明白的話,我很難。任何幫助,將不勝感激。

更新: 我想出了一個解決方案,使用後面的代碼來解決這個問題。如果有一種方法可以在不使用代碼的情況下做到這一點,那麼我就是所有人都知道的,但這是相當簡單直接的第一步和第二步,它並沒有真正打破邏輯脫離代碼的規則。

的XAML

<ListView x:Name="lv" ItemsSource="{Binding Columns, ElementName=reportGrid}" Grid.Column="0" Grid.Row="1" 
           Margin="5,160,25,30" SelectionMode="Multiple">       
         <ListView.View> 
          <GridView x:Name="gl"> 
           <GridViewColumn Width="50"> 
            <GridViewColumn.CellTemplate > 
             <DataTemplate x:Name="fieldChecked" > 
              <CheckBox IsChecked="{Binding IsVisible}" /> 
             </DataTemplate> 
            </GridViewColumn.CellTemplate> 
            <CheckBox Margin="0" x:Name="chkSelectAll" Click="chkSelectAll_Click" IsChecked="True" /> 
           </GridViewColumn> 
           <GridViewColumn Header="Check/Uncheck All" DisplayMemberBinding="{Binding Header}" Width="110"></GridViewColumn> 
          </GridView> 
         </ListView.View> 
        </ListView> 

背後

private void chkSelectAll_Click(object sender, RoutedEventArgs e) 
    { 
     if (chkSelectAll.IsChecked.Value == true) 
     { 
      for (int i = 0; i < lv.Items.Count; i++) 
      {      
       ListViewItem lvi = (ListViewItem)lv.ItemContainerGenerator.ContainerFromItem(lv.Items[i]); 

       if (lvi != null) 
       { 
        CheckBox c = lvi.FindChildByType<CheckBox>(); 
        c.IsChecked = true;       
       } 
      } 
     } 
     else 
     {     
      for (int i = 0; i < lv.Items.Count; i++) 
      { 
       ListViewItem lvi = (ListViewItem)lv.ItemContainerGenerator.ContainerFromItem(lv.Items[i]); 
       if (lvi != null) 
       { 
        CheckBox c = lvi.FindChildByType<CheckBox>(); 
        c.IsChecked = false; 
       } 
      }     
     } 
    } 

一個需要注意的代碼是列表視圖我不得不向下滾動到下看到所有的字段。如果我沒有這樣做,它不會取消選中所有的字段。如果(lvi!= null),我也必須在代碼行 中,因爲如果你沒有向下滾動,它會認爲列表中的項目是空的並且崩潰。

無論如何,這不是完美的,但這是我如何解決它。使用MVVM的任何更好的解決方案都不是那麼複雜而且難以實現,請賜教。

感謝

+0

更新...我無法弄清楚如何使用MVVM範例來解決方案,但是使用後面的代碼做了一些事情。我發現有時後面的代碼是最簡單的方法。只要我們在代碼背後沒有任何真正的邏輯,那麼誰在乎呢?無論如何。 xml – Paul

回答

0

哇..這是一個老問題,但不管是什麼原因仍然沒有得到答覆。

訴諸於VisualTreeHelper類型的東西幾乎從來都不是WPF中的最佳方法。它甚至比適當的基於DataBinding的方法「更容易」。在這種情況下,由於您正在處理UI特定的問題(顯示或隱藏DataGrid的列),因此不存在ViewModel,因此MVVM不適用於此處,並且後面的代碼完全有效。

但是,你看問題的錯誤的結束:試圖操縱的複選框(綁定目標),而不是簡單地操縱綁定來源(列本身):

private void chkSelectAll_Click(object sender, RoutedEventArgs e) 
{ 
    var visible = chkSelectAll.IsChecked ?? false; 
    foreach (var column in reportGrid.Columns) 
     column.Visibility = visible ? Visibility.Visible : Visibility.Collapsed;  
} 

通過修改Visibility屬性的值,每列的只讀IsVisible屬性將被更新,綁定將攜帶新值到每個相應CheckBox的CheckBox.IsChecked屬性。

0

如果有人像我一樣絆倒了這個惡作劇,有一個很好的方法來解決保羅提到的滾動問題:只需滾動代碼隱藏!

listView.ScrollIntoView(listView.Items[listView.Items.Count - 1]); 
listView.ScrollIntoView(listView.Items[0]); 

之後,你可以做的ItemContainerGenerator東西沒有得到空。

如果您想優化響應能力(特別是對於不經常更改的大型列表):當listView的源內容發生更改時,您只需查詢ItemContainerGenerator。因此,如果您將複選框放在單獨的列表中,則只需在用戶第一次單擊(全)選擇複選框時查詢ItemContainerGenerator ...

但是,您應該在De)選擇所有複選框,因爲如果在設置itemsSource並執行滾動之後立即爲CheckBoxes查詢ItemContainerGenerator,那麼最終還是會出現空值(我認爲,因爲GUI沒有足夠的時間來正確呈現ListView那時候)。

相關問題