Значение свойства, указанное в WPF XAML, вызывает исключение

#c# #wpf #xaml

#c# #wpf #xaml

Вопрос:

У меня есть проект WPF, где я использую простой вид сетки для привязки к элементам. Один из моих столбцов выглядит следующим образом:

 <GridViewColumn x:Key="GvcValue" Header="Value"
                            DisplayMemberBinding="{Binding (cmn:ElementData.Value)}" />
  

Как вы можете видеть, это определяет путь привязки на основе ожидаемого типа, чтобы обеспечить лучший рефакторинг и т.д. У меня также есть несколько других столбцов, которые используют эту систему для привязки к другим свойствам тех же типов объектов. Их определение точно такое же, за исключением имени свойства и, конечно, ключа. Всякий раз, когда отображается вид сетки, это немедленно вызывает это исключение:

 Key cannot be null.
Parameter name: key
   at System.Collections.Specialized.ListDictionary.get_Item(Object key)
   at System.Collections.Specialized.HybridDictionary.get_Item(Object key)
   at System.ComponentModel.PropertyChangedEventManager.AddListener(INotifyPropertyChanged source, String propertyName, IWeakEventListener listener, EventHandler`1 handler)
   at System.ComponentModel.PropertyChangedEventManager.AddHandler(INotifyPropertyChanged source, EventHandler`1 handler, String propertyName)
   at MS.Internal.Data.PropertyPathWorker.ReplaceItem(Int32 k, Object newO, Object parent)
   at MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState(Int32 k, ICollectionView collectionView, Object newValue, Boolean isASubPropertyChange)
   at MS.Internal.Data.ClrBindingWorker.AttachDataItem()
   at System.Windows.Data.BindingExpression.Activate(Object item)
   at System.Windows.Data.BindingExpression.AttachToContext(AttachAttempt attempt)
   at System.Windows.Data.BindingExpression.MS.Internal.Data.IDataBindEngineClient.AttachToContext(Boolean lastChance)
   at MS.Internal.Data.DataBindEngine.Task.Run(Boolean lastChance)
   at MS.Internal.Data.DataBindEngine.Run(Object arg)
   at MS.Internal.Data.DataBindEngine.OnLayoutUpdated(Object sender, EventArgs e)
   at System.Windows.ContextLayoutManager.fireLayoutUpdateEvent()
   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 System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext 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, Booleanamp; handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Booleanamp; handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(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(MSGamp; 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 System.Windows.Application.Run()
   at TestProject.App.Main()
  

Однако, как только я изменяю его на простую привязку к неквалифицированной строке, подобную этой:

 <GridViewColumn x:Key="GvcValue" Header="Value"
                            DisplayMemberBinding="{Binding Value}" />
  

оно работает без проблем и отображает то, что должно. Что еще более странно, я могу оставить все остальные указанные, и это все еще работает, только это вызывает проблему.

Думаю, я могу оставить это как привязку к строке, если мне нужно, но я хотел бы понять, что происходит, или даже как выяснить, что происходит. Кто-нибудь знает, какой столбец может вызвать подобную проблему?

Комментарии:

1. Это ресурс? Обычно это x:Name … не key

2. Это ресурс. Столбцы динамически добавляются в фоновом режиме на основе настроек родительского объекта, который содержит список… Однако это детали реализации моей программы, которые работают просто отлично, плюс все остальные столбцы также определяют свой ключ. Проблема связана с определением пути привязки, который вызывает проблему.

Ответ №1:

Это исключение происходит из-за того, что вы используете сокращенную версию для пути привязки, которая в обычных случаях работает, но здесь дает сбой.

Замените свой код на:

 <GridViewColumn x:Key="GvcValue" Header="Value" 
           DisplayMemberBinding="{Binding path=(cmn:ElementData.Value)}" />