1

NullReferenceException在我的视图模型中更新绑定属性时,我得到了一个。这只发生在我TreeView在视图中使用控件时。如果我用列表替换它,异常就会消失。

这是调试器在我的代码中中断的地方:

PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

大约 30 次调用之后,通过许多PresentationFrameworkWindowsBase程序集,异常实际上发生在这里:

PresentationFramework.dll!System.Windows.StyleHelper.EvaluateOldNewStates()

这是TreeView

<TreeView ItemsSource="{Binding Source={StaticResource cvs}, Path=Groups}"
          ItemTemplate="{StaticResource categoryTemplate}" DockPanel.Dock="Bottom" 
          SelectedItemChanged="TreeView_SelectedItemChanged"/>

如果我改用它ListBox,问题就会消失:

<ListBox DockPanel.Dock="Bottom" ItemsSource="{Binding ApplicationServers}" DisplayMemberPath="Name"
         SelectedItem="{Binding SelectedApplicationServer}" Height="auto"/>

我不确定这会有所帮助,但这里是更新的属性:

public ObservableCollection<ApplicationServer> ApplicationServers
{
    get { return this._applicationServers; }
    private set
    {
        this._applicationServers = value;
        this.NotifyPropertyChanged(() => this.ApplicationServers);
    }
}

这是更新该属性的调用:

this.ApplicationServers = new ObservableCollection<ApplicationServer>(ApplicationServerLogic.GetAll().ToList());

有没有人经历过这样的事情?
我不知道是什么导致了这个问题,我很想只使用ListBox.

确实,我现在几乎必须使用ListBox
我怎么能解决这个问题?可能是PresentationFramework程序集中的错误吗?

此外,这是我的视图的代码隐藏,显示了项目更改事件的处理。

private void TreeView_SelectedItemChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<object> e)
{           
    ((ApplicationServerViewModel)DataContext).SelectedApplicationServer = e.NewValue as ApplicationServer;
}

编辑

有人要求更多代码,所以这里是:

<CollectionViewSource x:Key="cvs" Source="{Binding ApplicationServers}">
    <CollectionViewSource.GroupDescriptions>
        <PropertyGroupDescription PropertyName="DeploymentEnvironment"/>
    </CollectionViewSource.GroupDescriptions>
    <CollectionViewSource.SortDescriptions>
        <scm:SortDescription PropertyName="Name" Direction="Ascending"/>
    </CollectionViewSource.SortDescriptions>
</CollectionViewSource>

<!-- Our leaf nodes (server names) -->
<DataTemplate x:Key="serverTemplate">
    <TextBlock Text="{Binding Path=Name}"/>
</DataTemplate>

<!-- Note: The Items path refers to the items in the 
     CollectionViewSource group (our servers).
     The Name path refers to the group name. -->
<HierarchicalDataTemplate x:Key="categoryTemplate" ItemsSource="{Binding Path=Items}"
                          ItemTemplate="{StaticResource serverTemplate}">
    <TextBlock Text="{Binding Path=Name}" FontWeight="Bold"/>
</HierarchicalDataTemplate>
4

2 回答 2

1

虽然它不能回答您的情况的原因;一种方法是将项目添加到集合实例而不是通过设置器更改实例。删除暴露的 setter 并根据需要简单地添加项目,这将CollectionChanged在基础集合上引发事件,这将为您提供最终需要的内容。

        public ObservableCollection<ApplicationServer> ApplicationServers
        {
            get { return this._applicationServers; }
        }

        ApplicationServers.Add(...);
于 2012-02-26T19:49:55.267 回答
-1

我知道这个问题很老了。


就我而言,我正在扩展 a TabControl,为其添加新功能。其中一项功能改变了SelectedIndex属性。

如果该属性连续多次更改,我会得到相同的异常。

此外,出于某种原因,我必须将其中一个选项卡设置为,IsSelected = true否则应用程序会在打开窗口时崩溃,但有类似的例外:

▬ Message - 
    Object reference not set to an instance of an object.
○ Type - 
    System.NullReferenceException
▲ Source - 
    PresentationFramework
▼ TargetSite - 
    Void EvaluateOldNewStates(System.Windows.MultiTrigger, System.Windows.DependencyObject, System.Windows.DependencyProperty, System.Windows.DependencyPropertyChangedEventArgs, Int32, System.Windows.Style, System.Windows.FrameworkTemplate, Boolean ByRef, Boolean ByRef)
♠ StackTrace - 
   at System.Windows.StyleHelper.EvaluateOldNewStates(MultiTrigger multiTrigger, DependencyObject triggerContainer, DependencyProperty changedProperty, DependencyPropertyChangedEventArgs changedArgs, Int32 sourceChildIndex, Style style, FrameworkTemplate frameworkTemplate, Boolean& oldState, Boolean& newState)
   at System.Windows.StyleHelper.OnTriggerSourcePropertyInvalidated(Style ownerStyle, FrameworkTemplate frameworkTemplate, DependencyObject container, DependencyProperty dp, DependencyPropertyChangedEventArgs changedArgs, Boolean invalidateOnlyContainer, FrugalStructList`1& triggerSourceRecordFromChildIndex, FrugalMap& propertyTriggersWithActions, Int32 sourceChildIndex)
   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.DependencyObject.SetCurrentValueInternal(DependencyProperty dp, Object value)
   at System.Windows.Controls.Primitives.Selector.SelectionChanger.CreateDeltaSelectionChange(List`1 unselectedItems, List`1 selectedItems)
   at System.Windows.Controls.Primitives.Selector.SelectionChanger.End()
   at System.Windows.Controls.Primitives.Selector.SelectionChanger.SelectJustThisItem(ItemInfo info, Boolean assumeInItemsCollection)
   at System.Windows.Controls.Primitives.Selector.OnSelectedIndexChanged(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.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
   at System.Windows.DependencyObject.SetCurrentValueInternal(DependencyProperty dp, Object value)
   at System.Windows.Controls.TabControl.OnGeneratorStatusChanged(Object sender, EventArgs e)
   at System.EventHandler.Invoke(Object sender, EventArgs e)
   at System.Windows.Controls.ItemContainerGenerator.SetStatus(GeneratorStatus value)
   at System.Windows.Controls.ItemContainerGenerator.Generator.System.IDisposable.Dispose()
   at System.Windows.Controls.Panel.GenerateChildren()
   at System.Windows.Controls.Panel.EnsureGenerator()
   at System.Windows.Controls.Panel.get_InternalChildren()
   at System.Windows.Controls.StackPanel.StackMeasureHelper(IStackMeasure measureElement, IStackMeasureScrollData scrollData, Size constraint)
   at System.Windows.Controls.StackPanel.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)
   at System.Windows.Controls.ScrollContentPresenter.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)
   at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV, Boolean& hasDesiredSizeUChanged)
   at System.Windows.Controls.Grid.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.ScrollViewer.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)
   at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV, Boolean& hasDesiredSizeUChanged)
   at System.Windows.Controls.Grid.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Control.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)
   at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV, Boolean& hasDesiredSizeUChanged)
   at System.Windows.Controls.Grid.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)
   at System.Windows.Controls.ContentPresenter.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Documents.AdornerDecorator.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Border.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Window.MeasureOverrideHelper(Size constraint)
   at System.Windows.Window.MeasureOverride(Size availableSize)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Interop.HwndSource.SetLayoutSize()
   at System.Windows.Interop.HwndSource.set_RootVisualInternal(Visual value)
   at System.Windows.Window.SetRootVisual()
   at System.Windows.Window.SetRootVisualAndUpdateSTC()
   at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight)
   at System.Windows.Window.CreateSourceWindow(Boolean duringShow)
   at System.Windows.Window.ShowHelper(Object booleanBox)
   at System.Windows.Window.ShowDialog()
   at MyApp.App.App_Startup(Object sender, StartupEventArgs e) in C:\fakepath\App.xaml.cs:line 223
   at System.Windows.Application.OnStartup(StartupEventArgs e)
   at System.Windows.Application.<.ctor>b__1_0(Object unused)
   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)
 

由于我正在处理该新控件的Style(inside Themes\Generic.xaml),因此我开始删除该自定义样式的部分内容,直到它再次开始工作。

我能够找到有问题的代码。我有两个,里面MultiTrigger有 2 和 3 Condition。每个MultiTrigger都有Enter/Exit Actions一个Storyboard里面。

通过替换MultiTriggerwithMultiDataTrigger并将Condition内部设置为使用 aBinding而不是直接访问该属性,它再次开始工作。

由此:

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="IsSelected" Value="True"/>
        <Condition Property="DisplayAccent" Value="True"/>
    </MultiTrigger.Conditions>

    <MultiTrigger.EnterActions>
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimation Duration="0:0:0:0.15" Storyboard.TargetName="SelectionBorder" Storyboard.TargetProperty="Opacity" To="1"/>
            </Storyboard>
        </BeginStoryboard>
    </MultiDataTrigger.EnterActions>
    <MultiDataTrigger.ExitActions>
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimation Duration="0:0:0:0.15" Storyboard.TargetName="SelectionBorder" Storyboard.TargetProperty="Opacity"/>
            </Storyboard>
        </BeginStoryboard>
    </MultiTrigger.ExitActions>
</MultiTrigger>

对此:

<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <Condition Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=IsSelected, FallbackValue=False}" Value="True"/>
        <Condition Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=DisplayAccent, FallbackValue=False}" Value="True"/>
    </MultiDataTrigger.Conditions>

    <MultiDataTrigger.EnterActions>
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimation Duration="0:0:0:0.15" Storyboard.TargetName="SelectionBorder" Storyboard.TargetProperty="Opacity" To="1"/>
            </Storyboard>
        </BeginStoryboard>
    </MultiDataTrigger.EnterActions>
    <MultiDataTrigger.ExitActions>
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimation Duration="0:0:0:0.15" Storyboard.TargetName="SelectionBorder" Storyboard.TargetProperty="Opacity"/>
            </Storyboard>
        </BeginStoryboard>
    </MultiDataTrigger.ExitActions>
</MultiDataTrigger>
于 2020-07-14T02:26:44.283 回答