2016-04-13 89 views
0

DataGridには、行の最初のセルにCheckboxが含まれています。私は自分のDataGrid行をループし、そのセルのCheckboxがチェックされていれば行を取得したいと思います。WPFでCheckBoxセルのブール値を取得する

これはDataGridをチェック中に私のコードです:

宜蘭の答えに基づいて編集:

Private Sub ApproveBtn_Clicked(sender As Object, e As RoutedEventArgs) 


    For i As Integer = 0 To TimeSheetAppDGrid.Items.Count - 1 

     TimeSheetAppDGrid.SelectedItem = TimeSheetAppDGrid.Items(i) 
     Dim row As Row = DirectCast(TimeSheetAppDGrid.SelectedItems(0), Row) 

     Dim mycheckbox = TryCast(TimeSheetAppDGrid.Columns(0).GetCellContent(TimeSheetAppDGrid.Items(i)), ContentPresenter) 
     If mycheckbox Is Nothing Then 
      Return 
     End If 
     Dim checkBox = GetAllVisualChildren(mycheckbox).OfType(Of CheckBox)().FirstOrDefault(Function(box) box.Name = "chkSelectAll") 
     If checkBox Is Nothing Then 
      Return 
     End If 

     Dim isChecked = checkBox.Checked 

     If isChecked = True Then 

      MsgBox(row.Mark) 

     End If 

    Next 


End Sub 

次のコードはコンパイルエラーが発生VB.NETに受け入れられていないようです"Value of type 'FrameworkElement' cannot be converted to 'CheckBox'." Webを検索した後、ほぼすべての回答にこのコードがありますが、C#で変換されました。

Dim mycheckbox As CheckBox = TryCast(TimeSheetAppDGrid.Columns(0).GetCellContent(TimeSheetAppDGrid.SelectedItems(0)), CheckBox) 

このlinkはコードを取得した場所です。以下は、C#のコードからのオリジナルラインです:

CheckBox mycheckbox = myGrid.Columns[5].GetCellContent(myGrid.Items[i]) as CheckBox; 

これは、DataGridのための私のXAMLです:

<DataGrid Name ="TimeSheetAppDGrid" Margin="16,200,48,0" CanUserSortColumns="False" CanUserReorderColumns="False" CanUserAddRows="False" AutoGenerateColumns="False" SelectionUnit="FullRow" 
        materialDesign:DataGridAssist.CellPadding="13 8 8 8" materialDesign:DataGridAssist.ColumnHeaderPadding="8" IsReadOnly="True" SelectionMode="Single" > 

    <DataGrid.Resources> 
     <Style TargetType="{x:Type DataGridRow}" BasedOn="{StaticResource MaterialDesignDataGridRow}"> 
      <EventSetter Event="MouseDoubleClick" Handler="Row_DoubleClick"/> 
     </Style> 
    </DataGrid.Resources> 

    <DataGrid.Columns> 

     <DataGridTemplateColumn> 
      <DataGridTemplateColumn.Header> 
       <CheckBox Name="AllChkBox" /> 
      </DataGridTemplateColumn.Header> 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <CheckBox Name="chkSelectAll" Margin="3.5 0 0 0" 
       IsChecked="{Binding IsChecked, ElementName=AllChkBox, 
            Mode=OneWay}"/> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 

     <DataGridTextColumn Binding="{Binding Path=Mark}" Header="Mark" Width="120" MaxWidth="120" 
     EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnEditingStyle}"/> 
     <materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=ProjectCode}" Header="Project Code" Width="130" MaxWidth="130" 
     EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/> 
     <materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=Project}" Header="Project" Width="250" MaxWidth="250" 
     EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/> 
     <materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=PM}" Header="Project Manager" Width="230" MaxWidth="230" 
     EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/> 
     <materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=Activity}" Header="Activity" Width="600" MaxWidth="600" 
     EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/> 
     <materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=Today}" Header="Date" Width="200" MaxWidth="200" 
     EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/> 
     <materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=Regular}" Header="Regular" Width="130" MaxWidth="130" 
     EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/> 
     <materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=Overtime}" Header="Overtime" Width="130" MaxWidth="130"            
     EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"> 
      <DataGridTextColumn.HeaderStyle> 
       <Style TargetType="{x:Type DataGridColumnHeader}" BasedOn="{StaticResource MaterialDesignDataGridColumnHeader}"> 
        <Setter Property="HorizontalAlignment" Value="Left" /> 
       </Style> 
      </DataGridTextColumn.HeaderStyle> 
      <DataGridTextColumn.ElementStyle> 
       <Style TargetType="{x:Type TextBlock}"> 
        <Setter Property="HorizontalAlignment" Value="Left" /> 
       </Style> 
      </DataGridTextColumn.ElementStyle> 
     </materialDesign:MaterialDataGridTextColumn> 
    </DataGrid.Columns> 

    <DataGrid.CellStyle> 
     <Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource MaterialDesignDataGridCell}"> 
      <Setter Property="BorderThickness" Value="0"/> 
     </Style> 
    </DataGrid.CellStyle> 
</DataGrid> 

任意の提案ですか?私の意見では

+0

"以下のコードは、VB.NETで受け入れられていないようです"。それは実際にはどういう意味ですか?コンパイルエラーがある場合は、エラーメッセージを出してください。そうすれば、私たちは何を探しているのか知っています。おそらく、元のC#コードを提供して、両方の言語を知っている私たちの翻訳者が翻訳上の問題を理解できるようにすることもできます。 – jmcilhinney

+0

ご迷惑をおかけして申し訳ございません。エラーが表示されます: 'FrameworkElement'型の値を 'CheckBox'に変換できません。 – Kreyah

+0

なぜこれをやろうとしているのですか?チェックボックスのIsCheckedプロパティに既にデータバインディングを使用しているので、簡単な方法でその情報を取得できます。 – auburg

答えて

1

あなたのキャストが正常に動作するように、Snoopを使用して生成されたビジュアルツリーを見て取らなければなりません。

最も簡単なアプローチは、Dictionary<int, DataGridRow>Checked/Uncheckedイベントで更新することです。CheckBoxです。

申し訳ありませんがコードはC#です。

XAML:

<CheckBox Name="AllChkBox" Checked="AllChkBox_Checked" Unchecked="AllChkBox_Unchecked" /> 

<CheckBox Name="chkSelectAll" Margin="3.5 0 0 0" 
      Checked="chkSelectAll_Checked" Unchecked="chkSelectAll_Unchecked" 
      IsChecked="{Binding IsChecked, ElementName=AllChkBox, Mode=OneWay}"/> 

コード:

Dictionary<int, DataGridRow> rows = new Dictionary<int, DataGridRow>(); 

    private void chkSelectAll_Checked(object sender, RoutedEventArgs e) 
    { 
     var cur_item = DGrid.CurrentItem; 
     int cur_index = DGrid.Items.IndexOf(cur_item); 

     if (cur_index == -1) // header checkbox is checked 
      return; 

     DataGridRow row = (DataGridRow)DGrid.ItemContainerGenerator.ContainerFromItem(cur_item); 
     rows.Add(DGrid.Items.IndexOf(cur_item), row);    
    } 

    private void chkSelectAll_Unchecked(object sender, RoutedEventArgs e) 
    { 
     var cur_item = DGrid.CurrentItem; 
     rows.Remove(DGrid.Items.IndexOf(cur_item)); 
    } 

    private void AllChkBox_Checked(object sender, RoutedEventArgs e) 
    { 
     foreach (var item in DGrid.Items) 
     { 
      DataGridRow row = (DataGridRow)DGrid.ItemContainerGenerator.ContainerFromItem(item); 
      rows.Add(DGrid.Items.IndexOf(item), row); 
     } 
    } 

    private void AllChkBox_Unchecked(object sender, RoutedEventArgs e) 
    { 
     rows.Clear(); 
    } 
+0

エラーが表示されないようにコードを編集しました。できます!ありがとう! – Kreyah

0

はあなたの採用、溶液中のいくつかの概念の誤差があります:

のCheckBox mycheckbox = myGrid.Columns [5] .GetCellContent(myGrid.Items [i])とのCheckBoxなど;

私はそれをチェックしましたし、私たちはあなたのケースで同様DataGridTemplateColumn.CellTemplateを使用する場合、セルの後ろのDataTemplateがあるので、受け入れられている値(mycheckboxは)のContentPresenterです(あなたがたDataTemplateを使用しているため) 。そのため、コードは実際には機能しません。

ContentPresenterの視覚的な子であるため、あなたが示唆している解決策はContentPresenterからチェックボックスオブジェクトを取得することです(このコードはC#に変換する必要があります) in Snoop)。

UpdateHereがGetAllVisualChildrenコードです:

public static class VisualTreeHelperExtensions 
{ 
    public static T FindParent<T>(this DependencyObject child) where T : DependencyObject 
    { 
     while (true) 
     { 
      //get parent item 
      DependencyObject parentObject = VisualTreeHelper.GetParent(child); 

      //we've reached the end of the tree 
      if (parentObject == null) return null; 

      //check if the parent matches the type we're looking for 
      T parent = parentObject as T; 
      if (parent != null) 
       return parent; 
      child = parentObject; 
     } 
    } 

    public static List<DependencyObject> GetAllVisualChildren(this DependencyObject parent) 
    { 
     var resultedList = new List<DependencyObject>(); 
     var visualQueue = new Queue<DependencyObject>(); 
     visualQueue.Enqueue(parent); 

     do 
     { 
      var depObj = visualQueue.Dequeue(); 
      var childrenCount = VisualTreeHelper.GetChildrenCount(depObj); 

      for (int i = 0; i < childrenCount; i++) 
      { 
       var v = VisualTreeHelper.GetChild(depObj, i); 
       visualQueue.Enqueue(v); 
      } 

      resultedList.Add(depObj); 
     } while (visualQueue.Count > 0); 

     resultedList.RemoveAt(0); 
     return resultedList; 
    } 

} 

  1. をVBにVisualTreeHelperExtensionsクラスをインポートするために、次のことを行うソリューションの一部として、C#クラスライブラリを作成します。 。
  2. 新しい作成されたプロジェクトにVisualTreeHelperExtensionsクラスを追加します。
  3. C#クラスライブラリをコンパイルします。
  4. 新しい(作成した)クラスライブラリを参照(dll)としてvb.netプロジェクトに追加します。

更新#3 - VBコードを変更

Dim mycheckbox = TryCast(TimeSheetAppDGrid.Columns(0).GetCellContent(TimeSheetAppDGrid.Items(0)), ContentPresenter) 
    If mycheckbox Is Nothing Then 
     Return 
    End If 
    Dim checkBox = mycheckbox.GetAllVisualChildren().OfType(Of CheckBox)().FirstOrDefault(Function(box) box.Name = "chkSelectAll") 
    If checkBox Is Nothing Then 
     Return 
    End If 

    Dim isChecked = checkBox.IsChecked 

    If isChecked = True Then 

     MsgBox("Checked") 

    End If 

VB.netチェックボックス例

  1. CheckBox Control WPF In VB.NET.

  2. CheckBox Class in .Net Framework(no any restriction to vb)

.Net CheckBoxにはすべてIsCheckedブール状態プレゼンターがあるためです。

よろしくお願いいたします。

+0

varの子がチェックされているかどうかを確認するにはどうすればよいですか? – Kreyah

+0

@Kreyah見てください、私はこの試みた1 – Ilan

+0

更新#: 薄暗いにisChecked = checkBox.Checked にisChecked = trueの場合、 のMsgBox(row.Mark) END IF、それが動作しない場合は – Kreyah

0

EDIT

[OK]を、ここでチェックボックスを探してビジュアルツリーを検索しなくて必要なものを達成するためのより洗練された方法です(再びC#でうまくいけば、翻訳することは困難ではありません)。

public class Student:INotifyPropertyChanged 
    { 
     private bool _isChecked; 

     public bool IsChecked 
     { 
      get { return _isChecked; } 
      set { _isChecked = value; 
       OnPropertyChanged("IsChecked"); 
      } 
     } 
     public string Mark { get; set; } 
     public string ProjectCode { get; set; } 
     public string Project { get; set; } 
     public string PM { get; set; } 
     public string Activity { get; set; } 
     public DateTime Today { get; set; } 
     public string Regular { get; set; } 
     public string Overtime { get; set; } 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
     { 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

私は、テストデータで自分のデータグリッドに行を追加します:データのXAMLで

  TimeSheetAppDGrid.ItemsSource = new List<Student>() 
      { 
       new Student { ProjectCode="Project1",Mark = "A",Today = DateTime.Today} 
      }; 

を第一に、私はINotifyPropertyChangedのを実装するにバインドするためにStudentクラスを作成しました テンプレートにバインドを変更していません。ヘッダーのチェックボックスにバインドしますが、生徒のIsCheckedプロパティにバインドして、ヘッダーセルのAllChkBoxチェックボックスにクリックしたハンドラーを追加しました。

<DataGridTemplateColumn> 
        <DataGridTemplateColumn.Header> 
         <CheckBox Click="AllChkBox_OnClick" Name="AllChkBox" /> 
        </DataGridTemplateColumn.Header> 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <CheckBox Name="chkSelectAll" Margin="3.5 0 0 0" 
       IsChecked="{Binding Path=IsChecked,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 
       </DataGridTemplateColumn> 

AllChkBoxのクリックされたハンドラ(AllChkBox_OnClick)では、各データソース(つまり、学生)とAllChkBoxににisCheckedプロパティを切り替えるには、値をチェックする:今、各項目のソース(すなわち学生)

 private void AllChkBox_OnClick(object sender, RoutedEventArgs e) 
     { 

      foreach (var s in TimeSheetAppDGrid.ItemsSource) 
      { 
       Student st = s as Student; 

       st.IsChecked = (bool) AllChkBox.IsChecked; 
      } 

     } 

は魚を必要とせずに対応するチェックボックスセルにバインドされている彼らにisCheckedプロパティ()のために問い合わせることができますチェックボックスのチェックの周りに(しゃれを言い訳)すなわち

private void ButtonBase_OnClick(object sender, RoutedEventArgs e) 
{ 
    foreach (var source in TimeSheetAppDGrid.ItemsSource) 
    { 
     Student st = source as Student; 

     if (st.IsChecked) 
      MessageBox.Show("Is Checked"); 
    } 
} 
+0

コンバータのif文を変換できません。私はchkは列のヘッダーのみを選択し、各行の最初のセルは選択していないと思う。 – Kreyah

関連する問題