本文介绍了在Silverlight DataGrid中,CheckBox的DataContext有时在检查/取消选中时为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个DataGrid。其中一个列是一个带有复选框的模板。当Checked或Unchecked事件触发时(它与两者同时发生),CheckBox的DataContext有时为空,这会导致我的代码出错。

I have a DataGrid. One of the columns is a template with a CheckBox in it. When the Checked or Unchecked events trigger, (it happens with both) the CheckBox's DataContext is sometimes null, which causes my code to error. It seems to be null most often if the mouse is moving while you press and release the button quickly (it's intermittent).

我听了CheckBox的DataContext的变化,如果鼠标移动的时候,通过创建视图:ListenCheckBox(扩展CheckBox)和附加绑定,它永远不会设置为 null,但它被设置为从null到一个任务的时候,我不会指望,即在DataGrid之后已完全生成,您正在检查/取消选中框。在[un]选中的事件运行一个空DataContext之后,我立即得到显示DataContext从null更改为任务的通知,所以看起来当我得到一个空DataContext,它是因为它没有实际设置DataContext当它运行Checked / Unchecked事件时。

I listened for changes to the DataContext of the CheckBox by making views:ListenCheckBox (extends CheckBox) and attaching a binding, and it's never set to null, but it is set from null to a Task at times I wouldn't expect, i.e. after the DataGrid has been totally generated and you're checking/unchecking boxes. Immediately after the [un]checked event runs with a null DataContext, I get the notification that shows the DataContext changed from null to a Task, so it appears that when I get a null DataContext, it's because it hadn't actually set the DataContext by the time it ran the Checked/Unchecked event.

此外,我添加了Tag ={Binding}到CheckBox进行调试。

Also, I added Tag="{Binding}" to the CheckBox for debugging. The Tag is not null (i.e. it has the proper object) more often than the DataContext, but still not all the time.

这里是XAML代码的相关位:

Here are the relevant bits of the XAML code:

<navigation:Page.Resources>
    <sdk:DataGridTemplateColumn x:Key="DeleteOrPrintSelect" Header="Delete Or Print Notes Selection">
        <sdk:DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <views:ListenCheckBox IsChecked="{Binding DeleteOrPrintNotesSelection, Mode=TwoWay}" Checked="DeletePrintNotesCheckBox_Changed" Unchecked="DeletePrintNotesCheckBox_Changed" HorizontalAlignment="Center" VerticalAlignment="Center" Tag="{Binding}" />
            </DataTemplate>
        </sdk:DataGridTemplateColumn.CellTemplate>
    </sdk:DataGridTemplateColumn>
</navigation:Page.Resources>


    <sdk:DataGrid x:Name="dataGrid1" Grid.Column="1" Grid.Row="2" AutoGeneratingColumn="dataGrid1_AutoGeneratingColumn">
        <sdk:DataGrid.RowGroupHeaderStyles>
            [removed]
        </sdk:DataGrid.RowGroupHeaderStyles>
    </sdk:DataGrid>

以及相关代码:

        // Create a collection to store task data.
        ObservableCollection<Task> taskList = new ObservableCollection<Task>();
        [code adding Tasks to taskList removed]

        PagedCollectionView panelListView = new PagedCollectionView(taskList);
        this.dataGrid1.ItemsSource = panelListView;
    }

    private void dataGrid1_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        if (e.PropertyName == "DeleteOrPrintNotesSelection")
        {
            e.Column = Resources["DeleteOrPrintSelect"] as DataGridTemplateColumn;
        }
        else
        {
            e.Column.IsReadOnly = true;
        }
    }

    private void DeletePrintNotesCheckBox_Changed(object sender, RoutedEventArgs e)
    {
        try
        {
            var cb = sender as CheckBox;
            var t = cb.DataContext as Task;
            t.DeleteOrPrintNotesSelection = cb.IsChecked == true;
            PagedCollectionView pcv = this.dataGrid1.ItemsSource as PagedCollectionView;
            ObservableCollection<Task> taskList = pcv.SourceCollection as ObservableCollection<Task>;
            bool anySelected = taskList.Any(x => x.DeleteOrPrintNotesSelection);
            this.btnPrint.IsEnabled = anySelected;
            this.btnDelete.IsEnabled = anySelected;
        }
        catch (Exception ex)
        {
            ErrorMessageBox.Show("recheck", ex, this);
        }
    }

任何想法?提前感谢。

推荐答案

我发现当您双击单元格并将其移动到单元格编辑模板。在我的例子中,我没有定义一个单元格编辑模板,所以它使用相同的单元格模板,但不是不改变任何东西,它显然决定做一个新的复选框。 我将列的IsReadOnly属性设置为true,并将其固定。另一种解决方案:

I found that the problem happened when you double click on the cell and it moved it to the cell editing template. In my case, I didn't have a cell editing template defined, so it used the same cell template, but instead of not changing anything, it apparently decided to make a new check box. I set the column's IsReadOnly property to true, and it fixed it. An alternate solution:

DataContext="{Binding}" (in XAML, or the code equivalent:)
cb.SetBinding(FrameworkElement.DataContextProperty, new Binding());



我不知道为什么这个修复它,因为我认为默认的DataContext是{Binding} 。也许这是一个Silverlight的错误,如果你明确定义它而不是保留默认值,它会以不同的顺序设置。

I'm not sure why this one fixes it, since I thought the default DataContext is {Binding}. Perhaps it's a Silverlight bug, and it gets set in a different order if you define it explicitly instead of leaving it the default.

这篇关于在Silverlight DataGrid中,CheckBox的DataContext有时在检查/取消选中时为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 20:57