none
datagrid设置ItemsSource的问题 RRS feed

  • 问题

  • 求助!之前一直没有问题,今天在测试的时候发现竟然报错了!
    我在一个页面里有两个datagrid,左边的dg选中一行相当于父,右边的datagrid会显示此行的一些孩子,这样就要求我每次选择不同的父时,左边的显示孩子的datagrid会刷新。
    这样每次刷新时,都要更新左边的datagrid的itemsSource。
    代码:

    DataModule.ocAttrDefTypeSelected.Clear();

    /////中间执行一些逻辑,重新往DataModule.ocAttrDefTypeSelected里添加孩子。

    datagrid右.itemsSource = DataModule.ocAttrDefTypeSelected;

    现在每次执行clear的时候都报错,“值不能为null,名称:key”
    2009年6月23日 6:57

答案

  • = .=看过之后发现你的左右说的很混乱

    我在一个页面里有两个datagrid,

    左边的dg选中一行相当于父,
                   右边的datagrid会显示此行的一些孩子,这样就要求我每次选择不同的父时,
    左边的显示孩子的datagrid会刷新。

    左边到底是列表选择,还是列表内容
    2009年6月23日 7:54
    版主
  • 用MyDataGrid.ItemsSource = null;就可以清空列表内容了

    还有这句
    "这样每次刷新时,都要更新左边的datagrid的itemsSource。"

    左边是选择列表也要用更新?

    S_S...

    参考下这个选择
    http://www.silverlightchina.com/sale/

    做选择列表用ListBox就行了,没必要用DataGrid的
    2009年6月23日 8:05
    版主

全部回复

  • = .=看过之后发现你的左右说的很混乱

    我在一个页面里有两个datagrid,

    左边的dg选中一行相当于父,
                   右边的datagrid会显示此行的一些孩子,这样就要求我每次选择不同的父时,
    左边的显示孩子的datagrid会刷新。

    左边到底是列表选择,还是列表内容
    2009年6月23日 7:54
    版主
  • 写错了,应该是右边的孩子的datagrid会刷新,左边是选择,右边是内容,
    现在在执行DataModule.ocAttrDefTypeSelected.Clear();时就会报错。
    2009年6月23日 7:56
  • 用MyDataGrid.ItemsSource = null;就可以清空列表内容了

    还有这句
    "这样每次刷新时,都要更新左边的datagrid的itemsSource。"

    左边是选择列表也要用更新?

    S_S...

    参考下这个选择
    http://www.silverlightchina.com/sale/

    做选择列表用ListBox就行了,没必要用DataGrid的
    2009年6月23日 8:05
    版主
  • 谢谢版主!不过现在的问题不是说如何清空列表,
    我定义了一个ObservableCollection<T> ocList 来存储内容。由于需要,我把这个ocList 定义成了static,
    然后  RightDataGrid.ItemsSource = ocList;
    这样,每次更新选择时,ocList也要更新。它始终存储的是当前选择项的内容。
    可是在执行 ocList.clear()时就会出错。

    而且,当判断 (ocList == null ) 或者 ocList.Count == 0  时, RightDataGrid.ItemsSource = null;
    这句会报同样的错误!,“值不能为null,名称:key”


    2009年6月23日 9:38
  • 你不能直接清空你的绑定源ocList,默认的绑定都是单向绑定,就是你更新这个泛型时,其绑定的控件会自动更新内容,当你把这个泛型清空或者设为null之后,其被绑定控件找不到内容就会报错,你可以选择OneTime方式进行绑定试试.

    这里3种绑定方式的区别于asp.net的绑定模式,应该重点看看.

    RightDataGrid.ItemsSource = null;这句是不会报错的,肯定是其前后程序的问题

    你可以
    RightDataGrid.ItemsSource = null;
    ....
    ocList = xxx;
    ....
    RightDataGrid.ItemsSource = ocList;

    这样对ocList操作时,先把ItemsSource设置为null,再操作ocList看看程序是不是还崩溃.

    2009年6月23日 10:02
    版主
  • 多谢版主!我试了一下,目前程序只要设置RightDataGrid.ItemsSource = null;
    就会报错。总是说参数名:key 不能为Null
    所以,上面说到的方法还是没办法尝试,我再看看代码。检查一下,郁闷!
    2009年6月24日 1:45
  • 把你全代码贴出来给你看看吧

    2009年6月24日 2:17
    版主
  •         public partial class Device : UserControl
        {
            ManagementPortTypeClient websvc = null;

            public Device()
            {
                InitializeComponent();

                websvc = Common.getMClient();

                websvc.GetDevicesCompleted += new EventHandler<GetDevicesCompletedEventArgs>(websvc_GetDevicesCompleted);

                websvc.GetAccessWaysCompleted += new EventHandler<GetAccessWaysCompletedEventArgs>(websvc_GetAccessWaysCompleted);

                query();
            }

             public void query()
            {
                GetDevicesType deviceType = new GetDevicesType();

                websvc.GetDevicesAsync(deviceType);
            }

            private void websvc_GetDevicesCompleted(object sender, GetDevicesCompletedEventArgs e)
            {
                if (e.Error != null)
                {
                    MessageBox.Show("从服务器端获取设备信息失败!");
                }
                else
                {
                    GetDevicesResponseType rt = new GetDevicesResponseType();
                   
                    rt = e.Result; 

                    DeviceType[] dts = rt.Results;

                    DataModule.ocDeviceType = Common.getDeviceType(dts);

                    if (rt != null)
                    {
                        devicesGrid.ItemsSource = DataModule.ocDeviceType;
                    }
                }
                
            }

            private void delG_Click(object sender, RoutedEventArgs e)
            {
                DeviceType dT = null;

                if (devicesGrid.SelectedItem != null)
                {
                    dT = (DeviceType)devicesGrid.SelectedItem;

                    DeleteDeviceType removeD = new DeleteDeviceType();
                   
                    removeD.DeviceID = dT.DeviceID.ToString();
                   
                    websvc.DeleteDeviceAsync(removeD); 

                    if (DataModule.ocDeviceType.Contains(dT))
                    {
                        DataModule.ocDeviceType.Remove(dT);
                    }
                    //// 删除设备时,删除其访问方式
                    DeleteAccessWayType deleteAwt = new DeleteAccessWayType();

                    foreach (AccessWayType awt in DataModule.ocAccessWayType)
                    {
                        deleteAwt.AccessWayID = awt.AccessWayID;
                        websvc.DeleteAccessWayAsync(deleteAwt);
                    }
                    DataModule.ocAccessWayType.Clear();
                }

            }

            private void refresh_Click(object sender, RoutedEventArgs e)
            {
                this.query();
            }

            private void devicesGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                if (e.AddedItems.Count > 0)
                {
                    DeviceType  dtSelected = (DeviceType)e.AddedItems[0];

                    gHint.Text = "设备"+dtSelected.DeviceName+"访问方式列表:";

                    GetAccessWaysType getAccessWayType = new GetAccessWaysType();
                   
                    getAccessWayType.DeviceID = dtSelected.DeviceID;

                    websvc.GetAccessWaysAsync(getAccessWayType);
                  
                }
            }
            private void websvc_GetAccessWaysCompleted(object sender, ServiceManagement.GetAccessWaysCompletedEventArgs e)
            {
                GetAccessWaysResponseType gawResponse = e.Result;

                AccessWayType[] awtList = gawResponse.Results;

                if ((awtList != null) && (awtList.Length > 0))
                {

                    DataModule.ocAccessWayType = Common.getAccessWayType(awtList);

                    this.accesswayGrid.ItemsSource = DataModule.ocAccessWayType;
                }
                else
                {
                    this.accesswayGrid.ItemsSource = null;     ////////////////////////////当设备没有访问方式时,  在这会有异常
                }
              
            }    
    }

    2009年6月24日 3:08
  • accesswayGrid这个DataGrid的定义呢?

    可以在Completed事件里面加一句
                if (e.Error == null)
                {
                  ..........
                }
    先判断,这样可以排除数据传输错误造成的影响
    2009年6月25日 1:13
    版主
  • 你用的是哪个版本? SL2? Dec release?  SL3 Beta?

    这个问题应该是SL2 10月版本中的一个Bug吧.
    2009年6月28日 5:18
  • 版本是:9.0.30729.146

    我自己单独也写了一个测试的例子,没有复杂的逻辑,每次点击按钮的时候,重新给datagrid 的itemsSource 设值。在重新设值之前,我都先执行一次itemsSource = null的操作,当按钮点击几次后,

    就会报同样的错误!

    真是奇怪!

    2009年6月30日 1:51
  • 版主

    accesswayGrid 的定义

    <my:DataGrid Margin="380,89,10,0" x:Name="accesswayGrid"  AutoGenerateColumns="False" ItemsSource="{Binding}">
                <my:DataGrid.Columns>
                    <my:DataGridTextColumn Header="访问方式ID" Binding="{Binding AccessWayID}" />
                    <my:DataGridTextColumn Header="访问方式"  Binding="{Binding Scheme}"/>
                    <my:DataGridTextColumn Header="主机名称" Binding="{Binding HostName}" />
                    <my:DataGridTextColumn Header="端口" Binding="{Binding Port}"/>
                    <my:DataGridTextColumn Header="访问路径" Binding="{Binding Path}"/>
                    <my:DataGridTextColumn Header="用户名" Binding="{Binding Username}" />
                    <my:DataGridTextColumn Header="密码" Binding="{Binding Password}"/>
                </my:DataGrid.Columns>
            </my:DataGrid>
    2009年6月30日 1:54
  • 版本是:9.0.30729.146

    我自己单独也写了一个测试的例子,没有复杂的逻辑,每次点击按钮的时候,重新给datagrid 的itemsSource 设值。在重新设值之前,我都先执行一次itemsSource = null的操作,当按钮点击几次后,

    就会报同样的错误!

    真是奇怪!

    http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=084a1bb2-0078-4009-94ee-e659c6409db0 下载DataGrid补丁= .=原来你用Silverlight 2开发
    2009年6月30日 10:18
    版主
  • 这个使用null就会报错的!
    我猜可能是源代码里面使用的是异步绑定的问题.
    努力!写一个js解析器,一个svg插件,一个绘图程序,做好自己,呵呵~!
    2009年8月9日 13:04
    版主
  • 八爪第一个在回复,后面一直再没有讨论,那我就把他的标记为正确,有什么疑问,欢迎继续讨论
    努力!完成了js解析器,还差一个svg插件,一个绘图程序,做好自己,呵呵~!
    2011年7月16日 13:40
    版主