4

当尝试在 DataGrid 上向下滚动时,我收到一个 InvalidOperationException 说明,“绑定表达式已经属于一个 BindingGroup;它不能添加到不同的 BindingGroup”。我不知道任何正在使用的 BindingGroups,所以我不确定它在说什么。我已将其缩小到仅出现在下面的列中。我怀疑它也与虚拟化有关。有任何想法吗?

这是 DataGrid 标记:

<DataGrid x:Name="dgStudentSNP" 
              AutoGenerateColumns="False"

              Grid.Row="1" Margin="6,10" 
              HorizontalAlignment="Stretch"
              HeadersVisibility="Column"
              CanUserSortColumns="True"
              CanUserAddRows="False"
              CanUserResizeColumns="True"
              CanUserDeleteRows="False"
              BorderThickness="1"
              SelectedValuePath="SNPEnrollmentID" VerticalScrollBarVisibility="Auto" VerticalAlignment="Top" Height="Auto" IsReadOnly="True">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Student Name" MinWidth="120">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock>
                                    <Hyperlink Click="GetStudentFamily" >
                                        <Run>
                                            <Run.Text >
                                                <MultiBinding StringFormat="{}{0} {1}">
                                                    <Binding Path="FirstName"/>
                                                    <Binding Path="LastName" />
                                                </MultiBinding>
                                            </Run.Text>                                                              
                                        </Run>
                                    </Hyperlink>
                            </TextBlock>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
              </DataGrid.Columns>
            </DataGrid>

这是异常的堆栈跟踪:

Stack Trace :    at System.Windows.Data.BindingExpressionBase.JoinBindingGroup(BindingGroup bg, Boolean explicitJoin)
   at System.Windows.Data.BindingExpressionBase.RejoinBindingGroup(Boolean isReflective, DependencyObject contextElement)
   at System.Windows.Data.BindingExpression.OnDataContextChanged(DependencyObject contextElement)
   at System.Windows.Data.BindingExpression.HandlePropertyInvalidation(DependencyObject d, DependencyPropertyChangedEventArgs args)
   at System.Windows.Data.BindingExpressionBase.OnPropertyInvalidation(DependencyObject d, DependencyPropertyChangedEventArgs args)
   at System.Windows.Data.BindingExpression.OnPropertyInvalidation(DependencyObject d, DependencyPropertyChangedEventArgs args)
   at System.Windows.Data.MultiBindingExpression.HandlePropertyInvalidation(DependencyObject d, DependencyPropertyChangedEventArgs args)
   at System.Windows.Data.BindingExpressionBase.OnPropertyInvalidation(DependencyObject d, DependencyPropertyChangedEventArgs args)
   at System.Windows.DependentList.InvalidateDependents(DependencyObject source, DependencyPropertyChangedEventArgs sourceArgs)
   at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
   at System.Windows.TreeWalkHelper.OnInheritablePropertyChanged(DependencyObject d, InheritablePropertyChangeInfo info)
   at System.Windows.DescendentsWalker`1._VisitNode(DependencyObject d)
   at System.Windows.DescendentsWalker`1.VisitNode(DependencyObject d)
   at System.Windows.DescendentsWalker`1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren)
   at System.Windows.DescendentsWalker`1.IterateChildren(DependencyObject d)
   at System.Windows.DescendentsWalker`1._VisitNode(DependencyObject d)
   at System.Windows.DescendentsWalker`1.VisitNode(DependencyObject d)
   at System.Windows.DescendentsWalker`1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren)
   at System.Windows.DescendentsWalker`1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren)
   at System.Windows.DescendentsWalker`1.IterateChildren(DependencyObject d)
   at System.Windows.DescendentsWalker`1._VisitNode(DependencyObject d)
   at System.Windows.DescendentsWalker`1.VisitNode(FrameworkElement fe)
   at System.Windows.DescendentsWalker`1.VisitNode(DependencyObject d)
   at System.Windows.DescendentsWalker`1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren)
   at System.Windows.DescendentsWalker`1.IterateChildren(DependencyObject d)
   at System.Windows.DescendentsWalker`1.StartWalk(DependencyObject startNode, Boolean skipStartNode)
   at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
   at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
   at System.Windows.Controls.ContentPresenter.OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
   at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp)
   at System.Windows.Data.BindingExpressionBase.Invalidate(Boolean isASubPropertyChange)
   at System.Windows.Data.BindingExpression.TransferValue(Object newValue, Boolean isASubPropertyChange)
   at System.Windows.Data.BindingExpression.Activate(Object item)
   at System.Windows.Data.BindingExpression.OnDataContextChanged(DependencyObject contextElement)
   at System.Windows.Data.BindingExpression.HandlePropertyInvalidation(DependencyObject d, DependencyPropertyChangedEventArgs args)
   at System.Windows.Data.BindingExpressionBase.OnPropertyInvalidation(DependencyObject d, DependencyPropertyChangedEventArgs args)
   at System.Windows.Data.BindingExpression.OnPropertyInvalidation(DependencyObject d, DependencyPropertyChangedEventArgs args)
   at System.Windows.DependentList.InvalidateDependents(DependencyObject source, DependencyPropertyChangedEventArgs sourceArgs)
   at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
   at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
   at System.Windows.Controls.ItemContainerGenerator.LinkContainerToItem(DependencyObject container, Object item, Boolean isRecycled)
   at System.Windows.Controls.ItemContainerGenerator.OnItemReplaced(Object oldItem, Object newItem, Int32 index)
   at System.Windows.Controls.ItemContainerGenerator.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
   at System.Windows.Controls.ItemContainerGenerator.System.Windows.IWeakEventListener.ReceiveWeakEvent(Type managerType, Object sender, EventArgs e)
   at System.Windows.WeakEventManager.DeliverEventToList(Object sender, EventArgs args, ListenerList list)
   at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)
   at System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
   at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
   at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
   at System.Windows.Controls.ItemCollection.System.Windows.IWeakEventListener.ReceiveWeakEvent(Type managerType, Object sender, EventArgs e)
   at System.Windows.WeakEventManager.DeliverEventToList(Object sender, EventArgs args, ListenerList list)
   at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)
   at System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
   at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
   at System.Windows.Data.ListCollectionView.ProcessCollectionChangedWithAdjustedIndex(NotifyCollectionChangedEventArgs args, Int32 adjustedOldIndex, Int32 adjustedNewIndex)
   at System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args)
   at System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
   at System.Windows.Controls.MultipleCopiesCollection.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
   at System.Windows.Controls.MultipleCopiesCollection.set_CopiedItem(Object value)
   at System.Windows.Controls.Primitives.DataGridCellsPresenter.OnItemChanged(Object oldItem, Object newItem)
   at System.Windows.Controls.DataGridRow.OnItemChanged(Object oldItem, Object newItem)
   at System.Windows.Controls.DataGridRow.NotifyPropertyChanged(DependencyObject d, String propertyName, DependencyPropertyChangedEventArgs e, DataGridNotificationTarget target)
   at System.Windows.Controls.DataGridRow.OnNotifyRowPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.Controls.DataGridRow.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
   at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
   at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
   at System.Windows.Controls.DataGridRow.PrepareRow(Object item, DataGrid owningDataGrid)
   at System.Windows.Controls.DataGrid.PrepareContainerForItemOverride(DependencyObject element, Object item)
   at System.Windows.Controls.ItemsControl.MS.Internal.Controls.IGeneratorHost.PrepareItemContainer(DependencyObject container, Object item)
   at System.Windows.Controls.ItemContainerGenerator.System.Windows.Controls.Primitives.IItemContainerGenerator.PrepareItemContainer(DependencyObject container)
   at System.Windows.Controls.VirtualizingStackPanel.InsertContainer(Int32 childIndex, UIElement container, Boolean isRecycled)
   at System.Windows.Controls.VirtualizingStackPanel.AddContainerFromGenerator(Int32 childIndex, UIElement child, Boolean newlyRealized)
   at System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(Size constraint)
   at System.Windows.Controls.Primitives.DataGridRowsPresenter.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.ContextLayoutManager.UpdateLayout()
   at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
   at System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()
   at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
   at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run(Window window)
   at Oasis.App.Main()
4

1 回答 1

3

将 BindingGroupName 设置为 null 确实有效。这对我来说很神秘,我希望其他更了解正在发生的事情的人会发布答案。但是,在上面发布的文档 eran otzap 中:

http://msdn.microsoft.com/en-us/library/system.windows.data.bindinggroup.aspx

它说:

您在 FrameworkElement 或 FrameworkContentElement 上设置 BindingGroup 属性。子元素从其父元素继承 BindingGroup,就像任何其他可继承属性一样。如果发生以下情况之一,则将后代元素上的绑定添加到 BindingGroup:

  • 绑定的源和具有 BindingGroup 的元素的 DataContext 是同一个对象,并且未设置 BindingGroupName 属性。

  • 绑定的 BindingGroupName 属性等于 BindingGroup 的名称,并且它们没有显式设置为 null。在地址的例子中,假设 Panel 的 DataContext 设置为 Address 类型的对象。每个 TextBox 的绑定都添加到面板的 BindingGroup 中。

看起来,当您在数据网格中使用多重绑定时,BindingGroup 与绑定的 BindingGroupName 不匹配,因此当您尝试更新这些绑定时会出现错误。

解决方案是将 MultiBinding 的 BindingGroupName 显式设置为 null,例如

   <MultiBinding StringFormat="{}{0} {1}" BindingGroupName="{x:Null}">
      <Binding Path="FirstName"/>
      <Binding Path="LastName" />
   </MultiBinding>

我不知道这会在以后产生什么影响,但它使这个特定的异常消失了。

于 2014-07-17T14:36:25.183 回答