我一直有一个困扰我一段时间的问题,但我相信我终于找到了。症状是,当我的一个绑定属性触发一个DataTrigger来交换ContentTemplate时,我的wpf控件将无法正确呈现。堆栈跟踪:

  System.ArgumentNullException: Value cannot be null.
  Parameter name: d
     at MS.Internal.Data.ElementObjectRef.GetObject(DependencyObject d, ObjectRefArgs args)
     at MS.Internal.Data.ObjectRef.GetDataObject(DependencyObject d, ObjectRefArgs args)
     at System.Windows.Data.BindingExpression.MS.Internal.Data.IDataBindEngineClient.VerifySourceReference(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)

调试器完全没有帮助,因为它只是在application.Run()上中断。以下是我根据实际的xaml所做的:
  <CollectionViewSource x:Key="SomeCollectionView"
                        Source="{Binding StatsByUser}"
                        IsLiveSortingRequested="True">
      <CollectionViewSource.SortDescriptions>
          <scm:SortDescription PropertyName="Amount" Direction="Descending"/>
          <scm:SortDescription PropertyName="Name" Direction="Ascending"/>
      </CollectionViewSource.SortDescriptions>
  </CollectionViewSource>

  <ItemsControl Background="Transparent" Width="{StaticResource Width}"
                ItemsSource="{Binding Source={StaticResource SomeCollectionView}}">
      <ItemsControl.Resources>
          <DataTemplate x:Key="FullViewTemplate">
              <Border Style="{StaticResource BorderStyle}">
                  <controls:FullCustomEntityControl CustomEntityObject="{Binding}"
                                                  Style="{StaticResource PanelStyle}"
                                                  MouseDown="Info_OnMouseDown"/>
              </Border>
          </DataTemplate>
          <DataTemplate x:Key="CompactViewTemplate">
              <Border Style="{StaticResource BorderStyle}">
                  <controls:CompactCustomEntityControl CustomEntityObject="{Binding}"
                                                     Style="{StaticResource PanelStyle}"
                                                     MouseDown="Info_OnMouseDown"/>
              </Border>
          </DataTemplate>
      </ItemsControl.Resources>
      <ItemsControl.ItemTemplate>
          <DataTemplate>
              <ContentControl Content="{Binding}">
                  <ContentControl.Style>
                      <Style TargetType="{x:Type ContentControl}">
                          <Setter Property="ContentTemplate" Value="{StaticResource FullViewTemplate}"/>
                          <Style.Triggers>
                              <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=c:ShellView}, Path=ViewModel.ShowCompactView}" Value="True">
                                  <Setter Property="ContentTemplate" Value="{StaticResource CompactViewTemplate}"/>
                              </DataTrigger>
                          </Style.Triggers>
                      </Style>
                  </ContentControl.Style>
              </ContentControl>
          </DataTemplate>
      </ItemsControl.ItemTemplate>
  </ItemsControl>

每当ViewModel.ShowCompactView引发PropertyChanged事件并启动DataTrigger时,它将切换ContentTemplate,然后抛出此错误。有没有解决这个问题的方法,或者更好的方法来构建不会导致这个问题的ContentTemplate交换?
编辑:潜在相关支持文章https://support.microsoft.com/en-us/kb/2461678
edit2:ui发生了什么的示例:c# - 如何根据绑定(bind)属性动态更改ContentTemplate?-LMLPHP。您可以看到大的插槽是FullCustomEntityControl,小的插槽是CompactCustomEntityControl。不改变任何一种模式都不会导致任何问题,但是让数据触发器改变它们会导致这样的问题。而且,使用的控件应该是一致的,而不是像这里这样的分裂。让它们处于任一模式,我的意思是移除数据触发器并选择其中一个。
edit3:一篇关于类似问题的文章,来自微软的人回应:https://social.msdn.microsoft.com/Forums/vstudio/en-US/fb4d0f41-bfea-409f-b8ac-e66558984b7a/argumentnullexception-when-displaying-wpf-window?forum=wpf
相关信息:
如果您在堆栈上收到verifysourcereference的argumentnullexception,那么肯定是由connect 561752中描述的问题引起的。即使你的应用程序没有直接使用elementname绑定,它也可能间接使用它们-几个内置控件使用elementname绑定:ComboBox、ContextMenu、Menuitem等。

最佳答案

每个itemscontrol都有ItemTemplateSelector属性,您可以利用它获得帮助。

10-04 14:23