2012-10-26 47 views
5

選擇通過DataGrid標題複選框中列的所有複選框我有一個CheckBoxColumn一個DataGrid。在該CheckBoxColumn的標題中,我添加了一個CheckBox來選擇該Datagrid行的所有複選框。如何在WPF的DataGrid

我該如何做到這一點?

我的XAML代碼WPF的數據網格:

<DataGrid AutoGenerateColumns="False" CanUserAddRows="False" Grid.RowSpan="2" Height="130" HorizontalAlignment="Left" IsReadOnly="False" Margin="189,340,0,0" Name="dgCandidate" TabIndex="7" VerticalAlignment="Top" Width="466" Grid.Row="1" > 
     <DataGrid.Columns> 
      <DataGridTextColumn x:Name="colCandidateID" Binding="{Binding CandidateID}" Header="SlNo" MinWidth="20" IsReadOnly="True" /> 
      <DataGridTextColumn x:Name="colRegistraion" Binding="{Binding RegisterNo}" Header="Reg. No." IsReadOnly="True" /> 
      <DataGridTextColumn x:Name="colCandidate" Binding="{Binding CandidateName}" Header="Name" MinWidth="250" IsReadOnly="True" /> 

      <DataGridTemplateColumn> 
       <DataGridTemplateColumn.Header> 
        <CheckBox Name="chkSelectAll" Checked="chkSelectAll_Checked" Unchecked="chkSelectAll_Unchecked"></CheckBox> 
       </DataGridTemplateColumn.Header> 
       <DataGridTemplateColumn.CellTemplate > 
        <DataTemplate > 
         <CheckBox x:Name="colchkSelect1" Checked="colchkSelect1_Checked" Unchecked="colchkSelect1_Unchecked" ></CheckBox> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 
      </DataGridTemplateColumn> 

     </DataGrid.Columns> 

    </DataGrid> 

回答

5

將您的候選類弄成這個樣子:

public class Candidate : DependencyObject 
{ 
    //CandidateID Dependency Property 
    public int CandidateID 
    { 
     get { return (int)GetValue(CandidateIDProperty); } 
     set { SetValue(CandidateIDProperty, value); } 
    } 
    public static readonly DependencyProperty CandidateIDProperty = 
     DependencyProperty.Register("CandidateID", typeof(int), typeof(Candidate), new UIPropertyMetadata(0)); 
    //RegisterNo Dependency Property 
    public int RegisterNo 
    { 
     get { return (int)GetValue(RegisterNoProperty); } 
     set { SetValue(RegisterNoProperty, value); } 
    } 
    public static readonly DependencyProperty RegisterNoProperty = 
     DependencyProperty.Register("RegisterNo", typeof(int), typeof(Candidate), new UIPropertyMetadata(0)); 
    //CandidateName Dependency Property 
    public string CandidateName 
    { 
     get { return (string)GetValue(CandidateNameProperty); } 
     set { SetValue(CandidateNameProperty, value); } 
    } 
    public static readonly DependencyProperty CandidateNameProperty = 
     DependencyProperty.Register("CandidateName", typeof(string), typeof(Candidate), new UIPropertyMetadata("")); 
    //BooleanFlag Dependency Property 
    public bool BooleanFlag 
    { 
     get { return (bool)GetValue(BooleanFlagProperty); } 
     set { SetValue(BooleanFlagProperty, value); } 
    } 
    public static readonly DependencyProperty BooleanFlagProperty = 
     DependencyProperty.Register("BooleanFlag", typeof(bool), typeof(Candidate), new UIPropertyMetadata(false)); 
} 

在MainWindow.xaml:

<DataGrid ItemsSource="{Binding CandidateList}"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Id" Binding="{Binding CandidateID}"/> 
     <DataGridTextColumn Header="RegNr" Binding="{Binding RegisterNo}"/> 
     <DataGridTextColumn Header="Name" Binding="{Binding CandidateName}"/> 
     <DataGridTemplateColumn> 
      <DataGridTemplateColumn.Header> 
       <CheckBox Checked="CheckBox_Checked" Unchecked="CheckBox_Checked"></CheckBox> 
      </DataGridTemplateColumn.Header> 
      <DataGridTemplateColumn.CellTemplate > 
       <DataTemplate> 
        <CheckBox IsChecked="{Binding BooleanFlag}"/> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
    </DataGrid.Columns> 
</DataGrid> 

在MainWindow.xaml.cs:

public MainWindow() 
    { 
     DataContext = this; 
     CandidateList.Add(new Candidate() 
     { 
      CandidateID = 1, 
      CandidateName = "Jack", 
      RegisterNo = 123, 
      BooleanFlag = true 
     }); 
     CandidateList.Add(new Candidate() 
     { 
      CandidateID = 2, 
      CandidateName = "Jim", 
      RegisterNo = 234, 
      BooleanFlag = false 
     }); 
     InitializeComponent(); 
    } 
    //List Observable Collection 
    private ObservableCollection<Candidate> _candidateList = new ObservableCollection<Candidate>(); 
    public ObservableCollection<Candidate> CandidateList { get { return _candidateList; } } 
    private void CheckBox_Checked(object sender, RoutedEventArgs e) 
    { 
     foreach (var item in CandidateList) 
     { 
      item.BooleanFlag = true; 
     } 
    } 
    private void UnheckBox_Checked(object sender, RoutedEventArgs e) 
    { 
     foreach (var item in CandidateList) 
     { 
      item.BooleanFlag = false; 
     } 
    } 
+0

給錯誤MyDataGridSourceList不存在樣本.. –

+0

這應該是DataGrid的源代碼。 (如果定義爲ObservableCollection ,則更好)另外,MyBooleanProperty應該是一個DependencyProperty,它是在繼承自DependencyObject的MyItemType中定義的。如果它太混亂讓我知道張貼更詳細的答案 – Bijan

+0

謝謝你.. 其實我對這個新的,所以這些都有點讓我困惑,所以請解釋這更多... –

2

我已經加入複選框在DataGrid行選擇所有複選框

,如果你的意思是在數據網格選擇所有複選框,然後我會說:只需用checked/unchecked來更新你的itemssource集合。

public bool SelectAll 
{ 
    get{return this._selectAll;} 
    set 
    { 
    this._selectAll = value; 
    this.MyItemsSourceCollection.ForEach(x=>x.MyRowCheckProperty=value); 
    this.OnPropertyChanged("SelectAll"); 
    } 
} 

XAML

 <DataGridTemplateColumn> 
      <DataGridTemplateColumn.Header> 
       <CheckBox isChecked="{Binding SelectAll}"></CheckBox> 
      </DataGridTemplateColumn.Header> 
      <DataGridTemplateColumn.CellTemplate > 
       <DataTemplate > 
        <CheckBox IsChecked="{Binding MyRowCheckProperty}"></CheckBox> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 

我不知道如果XAML綁定是正確的,但我希望你能看到我的本意

+0

其示值誤差不包含MyItemsSourceCollection –

+0

定義它,你必須使用你的屬性名稱 – blindmeis

+0

ü可以解釋這一點,請 –

3

嚴格地說模型不應該知道的視圖,並因此受到blindmeis,其中模型變化更新每一行DataGrid中提出的解決方案,休息MVVM /演示設計模式。請記住,在MVVM依賴流量視圖 - >視圖模型 - >模型,因此,如果您引用您的視圖模型(或控制代碼隱藏)控制,那麼你已經打破有效的模式,你可能會遇到的問題進一步下跌的軌道。

0

事實證明,這是一個相當困難得多得到的權利比人們希望。

第一個問題是,你不能只是綁定視圖模型列標題,因爲它不具有視圖模型作爲其數據的上下文,所以你需要一個結合代理正確地路由綁定到視圖模型。

public class BindingProxy : Freezable 
{ 
    public static readonly DependencyProperty DataProperty = DependencyProperty.Register(
     "Data", 
     typeof(object), 
     typeof(BindingProxy), 
     new UIPropertyMetadata(null)); 

    public object Data 
    { 
     get { return this.GetValue(DataProperty); } 
     set { this.SetValue(DataProperty, value); } 
    } 

    protected override Freezable CreateInstanceCore() 
    { 
     return new BindingProxy(); 
    } 
} 

現在,在您的數據網格的資源創建一個綁定代理:

<DataGrid.Resources> 
    <aon:BindingProxy 
     x:Key="DataContextProxy" 
     Data="{Binding}" /> 
</DataGrid.Resources> 

則列需要被定義爲:

<DataGridTemplateColumn> 
    <DataGridTemplateColumn.HeaderTemplate> 
     <DataTemplate> 
      <CheckBox 
       Command="{Binding 
        Data.SelectAllCommand, 
        Source={StaticResource DataContextProxy}}" 
       IsChecked="{Binding 
        Data.AreAllSelected, 
        Mode=OneWay, 
        Source={StaticResource DataContextProxy}, 
        UpdateSourceTrigger=PropertyChanged}" 
       IsThreeState="True" /> 
     </DataTemplate> 
    </DataGridTemplateColumn.HeaderTemplate> 
    <DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <CheckBox 
       IsChecked="{Binding 
        Path=IsSelected, 
        UpdateSourceTrigger=PropertyChanged}" /> 
     </DataTemplate> 
    </DataGridTemplateColumn.CellTemplate> 
</DataGridTemplateColumn> 

需要注意的是,需要有一個結合這兩個複選框的IsChecked依賴屬性及其Command屬性和IsChecked綁定OneWayIsChecked綁定獲取複選框以顯示項目的當前狀態,Command綁定執行批量選擇。你需要兩個。

在視圖模型

現在:

public bool? AreAllSelected 
{ 
    get 
    { 
     return this.Items.All(candidate => candidate.IsSelected) 
     ? true 
     : this.Items.All(candidate => !candidate.IsSelected) 
      ? (bool?)false 
      : null; 
    } 

    set 
    { 
     if (value != null) 
     { 
      foreach (var item in this.Items) 
      { 
       item.IsSelected = value.Value; 
      } 
     } 

     this.RaisePropertyChanged(); 
    } 
} 

而且SelectAllCommand屬性的ICommand的實現,其中Execute方法是:

public void Execute(object parameter) 
{ 
    var allSelected = this.AreAllSelected; 

    switch (allSelected) 
    { 
     case true: 
      this.AreAllSelected = false; 
      break; 
     case false: 
     case null: 
      this.AreAllSelected = true; 
      break; 
    } 
} 

最後你行項目視圖模型(即東西Items)每當IsSelected的值發生變化時,需要在主視圖模型上調整PropertyChanged。你如何做到這一點,取決於你。