none
DataGrid绑定Dictionary问题 RRS feed

  • 问题

  • 前台:

     <DataGridCheckBoxColumn Binding="{Binding IsSelected}" />

    后台:

    Dictionary<string, TagModel> dicTag = new Dictionary<string, TagModel>();

    TagModel tm = new TagModel ();

    dicTag.Add("Test",tm); dgTest.ItemsSource = dicTag.Values;

    TagModel.cs:

    private bool isSelected = false; 
    public bool IsSelected
            {
                get
                {
                    return isSelected;
                }
    
                set
                {
                    isSelected = value;
                }
            }


    运行后点击CheckBox就会弹出错误:此视图不允许“EditItem”。

    修改前台代码为:

    <DataGridTemplateColumn>
                                                            <DataGridTemplateColumn.CellTemplate>
                                                                <DataTemplate>
                                                                    <CheckBox  IsChecked="{Binding IsSelected}" />
                                                                </DataTemplate>
                                                            </DataGridTemplateColumn.CellTemplate>
                                                        </DataGridTemplateColumn>

    就能够正常使用。

    同时,如果使用第一种前台代码方式,只需要把后台代码改为:

    Dictionary<string, TagModel> dicTag = new Dictionary<string, TagModel>();
    
    TagModel tm = new TagModel ();
    
    dicTag.Add("Test",tm);
    
    List<TagModel> lstTM = new List<TagModel>(dicTag.Values);
    
    dgTest.ItemsSource = lstTM ;
    就不会报错了。

    请问为什么DataGridCheckBoxColumn绑定Dictionary的value会提示错误,而自定义DataGridTemplateColumn不会报错

    2013年5月17日 8:03

答案

  •   你好,

    是这样的,DataGrid DataGridTemplateColumn 分为CellTemplateCellEditingTemplate 两种情况,即:单元格不可编辑模式和单元格可编辑模式。

    当对cell进行编辑时,DataGridItemSource 需要一个继承了IList<T>接口的集合, Dictionary.Values 没有继承该接口,所以会报错。这也是为什么你将Dictionary.Values放入一个List中就可以成功的原因。

    >>修改前台代码就可以正常使用

    此示例摘自 DataGrid 类概述中提供的一个更大的示例。

    <sdk:DataGrid x:Name="dataGrid5" 
        Height="125" Margin="0,5,0,10"
        AutoGenerateColumns="False"
        RowBackground="Azure"
        AlternatingRowBackground="LightSteelBlue">
        <sdk:DataGrid.Columns>
            <!-- Name Column -->
            <sdk:DataGridTemplateColumn Header="Name">
                <sdk:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                            <TextBlock Padding="5,0,5,0"
                                Text="{Binding FirstName}"/>
                            <TextBlock Text="{Binding LastName}"/>
                        </StackPanel>
                    </DataTemplate>
                </sdk:DataGridTemplateColumn.CellTemplate> 
                <sdk:DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBox Text="{Binding FirstName}" BorderThickness="0"/>
                            <TextBox Text="{Binding LastName}" BorderThickness="0"/>
                        </StackPanel>
                    </DataTemplate>
                </sdk:DataGridTemplateColumn.CellEditingTemplate> 
            </sdk:DataGridTemplateColumn>              
            <!-- Address Column -->
            <sdk:DataGridTextColumn
                Header="Address" Width="300"
                Binding="{Binding Address}" />
        </sdk:DataGrid.Columns>
    </sdk:DataGrid>
    

     从上述代码可以看到,你修改的是不可编辑模式的模板,所以不会报错。如果你不想修改前台和后台代码的话,尝试将列的 IsReadOnly 属性设置为 true,则始终不会使用 CellEditingTemplate 属性值


    Lisa Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 Wurang 2013年5月23日 7:53
    2013年5月22日 2:51
    版主
  • 你好,

    >>但是对于与DataGridCheckBoxColumn还没有说明

    WPF为每个控件提供了相应的模板,DataGrid中得DataGridCheckBoxColumn也不例外,它就是有DataGridTemplateColumn 来定义得,所以,上个回复虽然说的是DataGridTemplateColumn 但是也是在间接的解释DataGridCheckBoxColumn。

    >>我对DataGridCheckBoxColumn的IsReadOnly赋值True,虽然不触发错误了,但是不能操作对应checkbox。请问这是为什么?

    将IsReadOnly 设为true之后,CellEditingTemplate不会被使用,所以你不会得到任何报错。但是同时,你这列也成了只读,不能进行操作。

      也就是说,如果你对该列进行操作且避免错误的话,你需要给DataGrid 的itemSource属性一个继承了IList<T>接口的集合。即像你后面那样改变后台代码(List<TagModel> lstTM = new List<TagModel>(dicTag.Values);)。这才是正确的做法。

    另外,推荐你熟悉下关于WPF Template的知识。

    这里有些博客,你可以看下:

    http://www.cnblogs.com/nankezhishi/archive/2009/07/08/datatemplate.html

    http://www.cnblogs.com/dingli/archive/2011/07/20/2112150.html


    Lisa Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 Wurang 2013年5月23日 7:53
    2013年5月23日 7:28
    版主

全部回复

  •   你好,

    是这样的,DataGrid DataGridTemplateColumn 分为CellTemplateCellEditingTemplate 两种情况,即:单元格不可编辑模式和单元格可编辑模式。

    当对cell进行编辑时,DataGridItemSource 需要一个继承了IList<T>接口的集合, Dictionary.Values 没有继承该接口,所以会报错。这也是为什么你将Dictionary.Values放入一个List中就可以成功的原因。

    >>修改前台代码就可以正常使用

    此示例摘自 DataGrid 类概述中提供的一个更大的示例。

    <sdk:DataGrid x:Name="dataGrid5" 
        Height="125" Margin="0,5,0,10"
        AutoGenerateColumns="False"
        RowBackground="Azure"
        AlternatingRowBackground="LightSteelBlue">
        <sdk:DataGrid.Columns>
            <!-- Name Column -->
            <sdk:DataGridTemplateColumn Header="Name">
                <sdk:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                            <TextBlock Padding="5,0,5,0"
                                Text="{Binding FirstName}"/>
                            <TextBlock Text="{Binding LastName}"/>
                        </StackPanel>
                    </DataTemplate>
                </sdk:DataGridTemplateColumn.CellTemplate> 
                <sdk:DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBox Text="{Binding FirstName}" BorderThickness="0"/>
                            <TextBox Text="{Binding LastName}" BorderThickness="0"/>
                        </StackPanel>
                    </DataTemplate>
                </sdk:DataGridTemplateColumn.CellEditingTemplate> 
            </sdk:DataGridTemplateColumn>              
            <!-- Address Column -->
            <sdk:DataGridTextColumn
                Header="Address" Width="300"
                Binding="{Binding Address}" />
        </sdk:DataGrid.Columns>
    </sdk:DataGrid>
    

     从上述代码可以看到,你修改的是不可编辑模式的模板,所以不会报错。如果你不想修改前台和后台代码的话,尝试将列的 IsReadOnly 属性设置为 true,则始终不会使用 CellEditingTemplate 属性值


    Lisa Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 Wurang 2013年5月23日 7:53
    2013年5月22日 2:51
    版主
  • 你好:

           关于DataGridTemplateColumn 的解释我已经理解了,但是对于与DataGridCheckBoxColumn还没有说明,我对DataGridCheckBoxColumn的IsReadOnly赋值True,虽然不触发错误了,但是不能操作对应checkbox。请问这是为什么?

    2013年5月23日 6:29
  • 你好,

    >>但是对于与DataGridCheckBoxColumn还没有说明

    WPF为每个控件提供了相应的模板,DataGrid中得DataGridCheckBoxColumn也不例外,它就是有DataGridTemplateColumn 来定义得,所以,上个回复虽然说的是DataGridTemplateColumn 但是也是在间接的解释DataGridCheckBoxColumn。

    >>我对DataGridCheckBoxColumn的IsReadOnly赋值True,虽然不触发错误了,但是不能操作对应checkbox。请问这是为什么?

    将IsReadOnly 设为true之后,CellEditingTemplate不会被使用,所以你不会得到任何报错。但是同时,你这列也成了只读,不能进行操作。

      也就是说,如果你对该列进行操作且避免错误的话,你需要给DataGrid 的itemSource属性一个继承了IList<T>接口的集合。即像你后面那样改变后台代码(List<TagModel> lstTM = new List<TagModel>(dicTag.Values);)。这才是正确的做法。

    另外,推荐你熟悉下关于WPF Template的知识。

    这里有些博客,你可以看下:

    http://www.cnblogs.com/nankezhishi/archive/2009/07/08/datatemplate.html

    http://www.cnblogs.com/dingli/archive/2011/07/20/2112150.html


    Lisa Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 Wurang 2013年5月23日 7:53
    2013年5月23日 7:28
    版主
  • 现在已经弄清楚了,非常感谢您的回复,祝工作顺利~
    2013年5月23日 7:53