简体   繁体   English

使用Silverlight / c#wpf遍历/循环Datagrid行以获取复选框列的值:NullReferenceException错误

[英]Iterate/Loop through Datagrid rows to get the value of checkbox column using Silverlight/ c# wpf: NullReferenceException error

I have a DataGrid in Silverlight xaml which contains three columns named Active(checkbox), name(Textcolumn), ID (Textcolumn) and a Save button outside the datagrid. 我在Silverlight xaml中有一个DataGrid,其中包含名为Active(复选框),名称(Textcolumn),ID(Textcolumn)的三列和datagrid外部的Save按钮。 I am getting the following error when I try to loop/iterate through the datagrid rows to get the value of the checkbox using GetCellContent. 当我尝试循环/遍历datagrid行以使用GetCellContent获取复选框的值时,出现以下错误。 GetCellContent works fine for first 20 rows but gives the NullReferenceException error after that. GetCellContent对于前20行工作正常,但此后给出NullReferenceException错误。 Please help. 请帮忙。

System.NullReferenceException: Object reference not set to an instance of an object.

XAML XAML

<StackPanel Orientation="Horizontal">
                    <Button Content ="Save" Click="SavePopUp_Click"/>
                    <TextBlock x:Name="GridHeader"  Style="{StaticResource GridHeaderStyle}" Margin="0,0,0,0" Width="445" Foreground="White" HorizontalAlignment="Right" TextAlignment="Center" Visibility="Collapsed"/>
</StackPanel>

<sdk:DataGrid  x:Name="dgloss">
    <sdk:DataGrid.RowDetailsTemplate>
                <DataTemplate>
                      <Border>
                           <Border Margin="2" Padding="2" BorderBrush="#AAAAAA" BorderThickness="2" CornerRadius="4">
                       </Border>
                     </Border>
                </DataTemplate>
        </sdk:DataGrid.RowDetailsTemplate>

        <sdk:DataGrid.Columns>

         <!--<sdk:DataGridCheckBoxColumn  IsReadOnly="False" Header="Active" Binding="{Binding Active, Mode=TwoWay}" CanUserResize="False" />-->
                        <sdk:DataGridTemplateColumn Header ="Active">
                            <sdk:DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <CheckBox x:Name="chkcode" Tag="{Binding Active}" Checked="HandleCheck" Unchecked="HandleUnchecked" IsThreeState="False" HorizontalAlignment ="Center" VerticalAlignment="Center" IsChecked="{Binding Active, Mode=TwoWay}" />
                                </DataTemplate>
                            </sdk:DataGridTemplateColumn.CellTemplate>
                            </sdk:DataGridTemplateColumn>

                            <sdk:DataGridTextColumn IsReadOnly="True" SortMemberPath="Name" Header="Name" Binding="{Binding Name, Mode=TwoWay}" Foreground="White"/>
                        <sdk:DataGridTextColumn x:Name="ID" IsReadOnly="True" SortMemberPath="ID" Header="ID" Binding="{Binding ID, Mode=TwoWay}" Foreground="White" Visibility="Visible"/>
         </sdk:DataGrid.Columns>

</sdk:DataGrid>

Save button Click event 保存按钮点击事件

    private void SavePopUp_Click(object sender, RoutedEventArgs e)
            {
               IEnumerable list = dgloss.ItemsSource as IEnumerable;
               List<string> lstFile = new List<string>();

               foreach (var row in list)
               {  
                   bool IsChecked = (bool)((CheckBox)dgloss.Columns[0].GetCellContent(row)).IsChecked;

                   if (IsChecked)
                   {
                      string id = ((TextBlock)grdLossCodelist.Columns[2].GetCellContent(row)).Text;
                       lstFile.Add(id);

}
}    
}

I had the same issue and determined that non-text cells (checkboxes, buttons, etc.) will only return their value if they are rendered, otherwise they return null. 我遇到了同样的问题,并确定非文本单元格(复选框,按钮等)仅在呈现时才会返回其值,否则将返回null。 Further, only the rows of the DataGrid that are displayed on the control are actually rendered. 此外,实际上仅呈现控件上显示的DataGrid行。 So in your case, I would bet that your DataGrid is sized such that it displays 20 rows at a time, so the 21st row returns null. 因此,在您的情况下,我敢打赌,您的DataGrid的大小应使其一次显示20行,因此第21行返回null。

What I wound up doing is iterating through the ItemSource instead of the DataGrid itself. 我最后要做的是遍历ItemSource而不是DataGrid本身。 Ultimately this is a better implementation anyway so as to not violate MVVM by mixing data access with UI. 最终,无论如何这都是一个更好的实现,以免通过将数据访问与UI混合而违反MVVM。

However, if you really want/need to do it using the DataGrid directly, you can force the cell to render in code: 但是,如果您确实希望/需要直接使用DataGrid进行操作,则可以强制该单元格在代码中呈现:

            foreach (var column in dataGrid.Columns)
            {
                DataGridTemplateColumn dgtColumn = null;
                DataGridBoundColumn dgbColumn = null;

                dgbColumn = column as DataGridBoundColumn;

                if (dgbColumn == null)
                {
                    dgtColumn = column as DataGridTemplateColumn;
                    CheckBox checkbox = (CheckBox)dgtColumn.CellTemplate.LoadContent();
                }
             }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM