【问题标题】:"Bounds cannot be changed while locked" on GridView updateGridView 更新上的“锁定时无法更改边界”
【发布时间】:2013-07-30 16:57:57
【问题描述】:

我有一个名为“myResults”的列表。当列表至少包含一项时,我正在尝试为列表填充带有信息的 GridView; GridView 被称为“gvMyResults”。但是,有时,在 DataSource 的此更新期间,我收到异常消息“锁定时无法更改边界”,并且在我的 GridView 上显示一个红色 X。我在我的更新周围添加了这个 Dispatcher 包装器,但我仍然看到同样的错误。很难排除故障,因为它不会每次都发生。此外,这个 GridView 是 Telerik RadGridView。

有谁知道如何阻止这个“锁定时不能更改边界”错误?

if (myResults.Count > 0) 
{
    Dispatcher.CurrentDispatcher.Invoke(
        DispatcherPriority.Normal, 
        (Action)delegate()
    {
        this.gvMyResults.DataSource = myResults;
    });
}

我也试过了,但得到了同样的异常:

_Context.Send(x =>
{
    this.gvMyResults.DataSource = myResults;
}, null);

异常/堆栈跟踪(根据要求):

Type=System.InvalidOperationException
Source=Telerik.WinControls
Message=Bounds cannot be changed while locked.
StackTrace:
    at Telerik.WinControls.RadElement.SetBoundsCore(Rectangle bounds)
    at Telerik.WinControls.RadElement.set_Size(Size value)
    at Telerik.WinControls.RadElement.SetLayoutParams(PointF newOffset, SizeF newSize)
    at Telerik.WinControls.RadElement.ArrangeCore(RectangleF finalRect)
    at Telerik.WinControls.RadElement.Arrange(RectangleF finalRect)
    at Telerik.WinControls.UI.RowsContainerElement.ArrangeOverride(SizeF finalSize)
    at Telerik.WinControls.RadElement.ArrangeCore(RectangleF finalRect)
    at Telerik.WinControls.RadElement.Arrange(RectangleF finalRect)
    at Telerik.WinControls.UI.ScrollViewElement`1.ArrangeViewElement(RectangleF viewElementRect)
    at Telerik.WinControls.UI.ScrollViewElement`1.ArrangeOverride(SizeF finalSize)
    at Telerik.WinControls.RadElement.ArrangeCore(RectangleF finalRect)
    at Telerik.WinControls.RadElement.Arrange(RectangleF finalRect)
    at Telerik.WinControls.Layouts.ContextLayoutManager.UpdateLayout()
    at Telerik.WinControls.RadElement.UpdateLayout()
    at Telerik.WinControls.UI.GridVisibilityHelper.EnsureRowVisible(GridViewRowInfo rowInfo)
    at Telerik.WinControls.UI.GridTableElement.EnsureRowVisible(GridViewRowInfo rowInfo)
    at Telerik.WinControls.UI.GridTableElement.EnsureCellVisible(GridViewRowInfo rowInfo, GridViewColumn column)
    at Telerik.WinControls.UI.GridTableElement.UpdateViewCore(Object sender, DataViewChangedEventArgs args)
    at Telerik.WinControls.UI.GridTableElement.UpdateView(Object sender, DataViewChangedEventArgs args)
    at Telerik.WinControls.UI.GridTableElement.ProcessTemplateEvent(GridViewEvent eventData)
    at Telerik.WinControls.UI.GridTableElement.Telerik.WinControls.UI.IGridViewEventListener.ProcessEvent(GridViewEvent eventData)
    at Telerik.WinControls.UI.GridViewEventProcessEntity.ProcessCollection(GridViewEvent gridEvent, PriorityWeakReferenceList list, GridEventProcessMode processMode)
    at Telerik.WinControls.UI.GridViewEventProcessEntity.ProcessEvent(GridViewEvent gridEvent)
    at Telerik.WinControls.UI.GridViewSynchronizationService.NotifyListeners(GridViewEvent gridEvent)
    at Telerik.WinControls.UI.GridViewSynchronizationService.FlushEvents()
    at Telerik.WinControls.UI.GridViewSynchronizationService.DispatchEvent(GridViewEvent gridEvent)
    at Telerik.WinControls.UI.GridViewSynchronizationService.RaiseCurrentChanged(GridViewTemplate template, GridViewRowInfo row, GridViewColumn column, Boolean user)
    at Telerik.WinControls.UI.GridViewTemplate.CollectionView_CurrentChanged(Object sender, EventArgs e)
    at System.EventHandler.Invoke(Object sender, EventArgs e)
    at Telerik.WinControls.Data.RadCollectionView`1.OnCurrentChanged(EventArgs args)
    at Telerik.WinControls.Data.RadCollectionView`1.SetCurrentPositionCore(Int32 newPosition, Boolean forceNotify, CurrentChangeReason reason)
    at Telerik.WinControls.Data.RadDataView`1.SyncCurrent(TDataItem item)
    at Telerik.WinControls.Data.RadDataView`1.RebuildData(Boolean notify)
    at Telerik.WinControls.Data.RadDataView`1.RefreshOverride()
    at Telerik.WinControls.Data.RadDataView`1.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args)
    at Telerik.WinControls.Data.RadCollectionView`1.source_CollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
    at Telerik.WinControls.Data.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
    at Telerik.WinControls.Data.RadListSource`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    at Telerik.WinControls.Data.RadListSource`1.EndUpdate(Boolean notifyUpdates)
    at Telerik.WinControls.Data.RadListSource`1.Initialize()
    at Telerik.WinControls.Data.RadListSource`1.Bind(Object dataSource, String dataMember)
    at Telerik.WinControls.Data.RadListSource`1.set_DataSource(Object value)
    at Telerik.WinControls.UI.GridViewTemplate.set_DataSource(Object value)
    at Telerik.WinControls.UI.RadGridView.set_DataSource(Object value)
    at MyProject.MyWindow.<>c__DisplayClass2.<DisplayCallerInfo>b__0() 

【问题讨论】:

  • 我们也在 Telerik 的论坛上发帖,但还没有听到任何消息 - link
  • 堆栈跟踪呢?
  • @KingKing - 我添加了 Stack-Trace。谢谢
  • 这些控件不是线程安全的。你试过 gvMyResults.Invoke(new MethodInvoker(() => { this.gvMyResults.DataSource = myResults; }));

标签: c# winforms telerik radgridview


【解决方案1】:

此错误表示网格未处于有效状态。我在代码 sn-p 中注意到您异步更新数据源,我想澄清一下,所有 UI 控件都不是整个 Windows 窗体 UI 平台中的线程安全控件。这是 MSDN 上的 article,描述了如何制作线程安全的 Winforms UI 应用程序。这意味着 RadGridView 也不是线程安全的,并且不能在主 UI 线程之外使用。您应该使用Invoke 来更新跨线程场景中的控件。例如:

if (gvMyResults.InvokeRequired)
{
   gvMyResults.Invoke(new MethodInvoker(() => { this.gvMyResults.DataSource = myResults; }));
}
else
{ 
 this.gvMyResults.DataSource = myResults;
}

【讨论】:

  • 谢谢@Ajay。我会对此进行测试并相应地奖励赏金。
  • 希望对您有所帮助
  • 到目前为止它似乎正在工作。我应该在今天晚些时候完成测试。
  • 完成后告诉我
猜你喜欢
  • 1970-01-01
  • 2019-10-31
  • 1970-01-01
  • 2013-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多