我一直在困擾着我一段時間,但我相信我終於找到了它。症狀是當我的一個綁定屬性觸發DataTrigger
時,我的WPF控件無法正確呈現,即將ContentTemplate
換掉。堆棧跟蹤:如何根據綁定屬性動態更改ContentTemplate?
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的例子:。你可以看到大插槽是
FullCustomEntityControl
,小插槽是CompactCustomEntityControl
。將它們保留在任何一種模式而不改變它都不會導致任何問題,但讓數據觸發器改變它們會導致類似的問題。此外,所使用的控制應該是一致的,而不是看起來像在這裏分裂。通過將它們留在任何一種模式下,我的意思是刪除數據觸發器並選擇其中一個。
EDIT3:一個類似的問題發帖與微軟的人回答:https://social.msdn.microsoft.com/Forums/vstudio/en-US/fb4d0f41-bfea-409f-b8ac-e66558984b7a/argumentnullexception-when-displaying-wpf-window?forum=wpf
相關信息:
如果你在堆棧上得到一個ArgumentNullException與VerifySourceReference,它肯定所致連接561752中描述的問題。即使您的應用程序沒有直接使用ElementName綁定,它也可能間接使用它們 - 幾個內置控件使用ElementName綁定:ComboBox,ContextMenu,MenuItem等。
我很好奇,如果有能見度結合將是有效的兩個'ItemsControl'。即使控件不可見,是否還有額外的處理開銷? – Lunyx
更改'ContentTemplate'是一個可靠的解決方案,不應該導致'ArgumentNullException'本身。問題可能來自您的控件'CompactCustomEntityControl'和'FullCustomEntityControl'。 [啓用拋出的CLR異常](https://msdn.microsoft.com/en-us/library/x85tt0dd.aspx),你可以得到在VS調試中拋出異常的實際位置。 –
我試着用簡化的例子重新創建了你的問題(刪除了你的自定義控件,CollectionViewSource等等),並且一切似乎都奏效了 - 它確實用我的TextBlock模板切換了我的TextBox模板......我建議你試着創建簡單的例子,並從那裏添加缺失的部分,直到找到真正的根本原因 –