xaml第二次打开弹出错误

时间:2017-03-02 10:44:36

标签: c# wpf

我在弹出窗口的DataGrid中显示搜索结果,一旦选择了一个项目,关闭弹出窗口并在页面上显示所选项目。这一切都适用于第一次打开和关闭,但是当我尝试重新打开弹出窗口时,我得到一个未处理的异常“在OnPropertyChanged(”IsOpen“)上的”PresentationFramework.dll“中出现类型'System.InvalidOperationException'的未处理异常调用

查看:

<Button x:Name="btSearch" Command="{Binding SearchNoteCommand}">
    <Image Source="images/search.jpg"/>
</Button>
<GroupBox x:Name="grpSearchPopup" VerticalAlignment="Top" HorizontalAlignment="Left" Height="51" Width="170" BorderBrush="{x:Null}" BorderThickness="0">
    <Popup Name="popSearch" IsOpen="{Binding IsOpen}" Margin="122,89,0,0">
        <Grid>
            <DataGrid Name="dgSearchResults" AutoGenerateColumns="False" ItemsSource="{Binding Path=CurrentNote.SearchResults}" SelectedItem="{Binding SelectedItem}" AlternatingRowBackground="#FFED676E" AlternationCount="2" Background="{x:Null}" >
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding NoteID}" Width="25" Header="ID"/>
                    <DataGridTextColumn Binding="{Binding Note}" Width="100" Header="Note"/>
                    <DataGridTextColumn Binding="{Binding Date}" Width="70" Header="Date"/>
                    <DataGridTextColumn Binding="{Binding Time}" Width="60" Header="Time"/>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Popup>
</GroupBox>

视图模型:

private bool _isOpen;
public bool IsOpen
{
    get { return _isOpen; }
    set
    {
        if (_isOpen == value) return;
        _isOpen = value;
        OnPropertyChanged("IsOpen");
    }
}
private NoteModel.SearchResult _selectedItem;
public NoteModel.SearchResult SelectedItem
{
    get { return _selectedItem; }
    set
    {
        if (value != _selectedItem)
        {
            _selectedItem = value;
            OnPropertyChanged("SelectedItem");
            if (_selectedItem != null)
            {
                noteData.FetchNote(CurrentNote, _selectedItem.NoteID);
                OnPropertyChanged("CurrentNote");
                //close the popup for search results
                IsOpen = false;
            }
        }
    }
}
private ICommand _searchNote;
public ICommand SearchNoteCommand
{
    get
    {
        if (_searchNote == null)
        {
            _searchNote = new RelayCommand(
                p => this.CanSearchNote(),
                p => this.SearchNote());
        }
        return _searchNote;
    }
}
private bool CanSearchNote()
{
    if (Search != null)
        return true;
    return false;
}
private void SearchNote()
{
    noteData.SearchNotes(CurrentNote, Search);
    //open the popup for search
    IsOpen = true;
}

此处发生错误:

protected virtual void OnPropertyChanged(string propertyName)
{
    this.VerifyPropertyName(propertyName);

    if (this.PropertyChanged != null)
    {
         var e = new PropertyChangedEventArgs(propertyName);   
         this.PropertyChanged(this, e);   <----- error
    }
}

NoteData.cs

public bool SearchNotes(NoteModel CurrentNote, string sSearch)
        {
            //check the open connection
            if (ConnectData.OpenConnection() == true)
            {
                try
                {
                    string SQLSearch = "select note_id, date, time, note from note where date like '%" + sSearch + "%' or time like '%" + sSearch + "%' or note like '%" + sSearch + "%' group by note_id, date, time, note";

                    //get the phone types for lookups
                    SqlCommand cmdSearchNotes = new SqlCommand(SQLSearch, ConnectData.connection);
                    SqlDataReader drSearchResults = cmdSearchNotes.ExecuteReader();
                    CurrentNote.SearchResults = new List<NoteModel.SearchResult>();

                    while (drSearchResults.Read())
                    {
                        CurrentNote.SearchResults.Add(new NoteModel.SearchResult()
                        {
                            NoteID = (int)drSearchResults["note_id"],
                            Date = drSearchResults["date"].ToString(),
                            Time = drSearchResults["time"].ToString(),
                            Note = (string)drSearchResults["note"]
                        });
                    }
                    drSearchResults.Dispose();
                    cmdSearchNotes.Dispose();

                    //close Connection
                    ConnectData.CloseConnection();

                    return true;
                }
                catch (SqlException ex)
                {
                    return false;
                    throw new ApplicationException("Something went wrong with fetching the note search results: ", ex);
                }
            }
            //connection failed
            else
            {
                return false;
            }
        }

public bool FetchNote(NoteModel CurrentNote, int NoteID)
{
    //check the open connection
    if (ConnectData.OpenConnection() == true)
    {
        try
        {
            string SQLSearch = "select note_id, date, time, note from note where note_id = " + NoteID;

            //get the phone types for lookups
            SqlCommand cmdFetchNote = new SqlCommand(SQLSearch, ConnectData.connection);
            SqlDataReader drFetchNote = cmdFetchNote.ExecuteReader();

            while (drFetchNote.Read())
            {
                CurrentNote.NoteID = (int)drFetchNote["note_id"];
                CurrentNote.Date = drFetchNote["date"].ToString();
                CurrentNote.Time = drFetchNote["time"].ToString();
                CurrentNote.Note = (string)drFetchNote["note"];
                CurrentNote.SearchResults = null;
            }
            drFetchNote.Dispose();
            cmdFetchNote.Dispose();

            //close Connection
            ConnectData.CloseConnection();

            return true;
        }
        catch (SqlException ex)
        {
            return false;
            throw new ApplicationException("Something went wrong with fetching the note: ", ex);
        }
    }
    //connection failed
    else
    {
        return false;
    }
}

堆栈追踪:

   σε System.Windows.Controls.ItemContainerGenerator.Verify()
   σε System.Windows.Controls.VirtualizingStackPanel.MeasureChild(IItemContainerGenerator& generator, IContainItemStorage& itemStorageProvider, IContainItemStorage& parentItemStorageProvider, Object& parentItem, Boolean& hasUniformOrAverageContainerSizeBeenSet, Double& computedUniformOrAverageContainerSize, Double& computedUniformOrAverageContainerPixelSize, Boolean& computedAreContainersUniformlySized, IList& items, Object& item, IList& children, Int32& childIndex, Boolean& visualOrderChanged, Boolean& isHorizontal, Size& childConstraint, Rect& viewport, VirtualizationCacheLength& cacheSize, VirtualizationCacheLengthUnit& cacheUnit, Boolean& foundFirstItemInViewport, Double& firstItemInViewportOffset, Size& stackPixelSize, Size& stackPixelSizeInViewport, Size& stackPixelSizeInCacheBeforeViewport, Size& stackPixelSizeInCacheAfterViewport, Size& stackLogicalSize, Size& stackLogicalSizeInViewport, Size& stackLogicalSizeInCacheBeforeViewport, Size& stackLogicalSizeInCacheAfterViewport, Boolean& mustDisableVirtualization, Boolean isBeforeFirstItem, Boolean isAfterFirstItem, Boolean isAfterLastItem, Boolean skipActualMeasure, Boolean skipGeneration, Boolean& hasBringIntoViewContainerBeenMeasured, Boolean& hasVirtualizingChildren)
   σε System.Windows.Controls.VirtualizingStackPanel.MeasureOverrideImpl(Size constraint, Nullable`1& lastPageSafeOffset, List`1& previouslyMeasuredOffsets, Nullable`1& lastPagePixelSize, Boolean remeasure)
   σε System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(Size constraint)
   σε System.Windows.Controls.Primitives.DataGridRowsPresenter.MeasureOverride(Size constraint)
   σε System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   σε System.Windows.UIElement.Measure(Size availableSize)
   σε System.Windows.ContextLayoutManager.UpdateLayout()
   σε System.Windows.UIElement.UpdateLayout()
   σε System.Windows.Interop.HwndSource.SetLayoutSize()
   σε System.Windows.Interop.HwndSource.set_RootVisualInternal(Visual value)
   σε System.Windows.Interop.HwndSource.set_RootVisual(Visual value)
   σε System.Windows.Controls.Primitives.Popup.SetRootVisualToPopupRoot()
   σε System.Windows.Controls.Primitives.Popup.CreateWindow(Boolean asyncCall)
   σε System.Windows.Controls.Primitives.Popup.OnIsOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
   σε System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   σε System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   σε System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
   σε System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
   σε System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp, Boolean preserveCurrentValue)
   σε System.Windows.Data.BindingExpressionBase.Invalidate(Boolean isASubPropertyChange)
   σε System.Windows.Data.BindingExpression.TransferValue(Object newValue, Boolean isASubPropertyChange)
   σε System.Windows.Data.BindingExpression.ScheduleTransfer(Boolean isASubPropertyChange)
   σε MS.Internal.Data.ClrBindingWorker.NewValueAvailable(Boolean dependencySourcesChanged, Boolean initialValue, Boolean isASubPropertyChange)
   σε MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState(Int32 k, ICollectionView collectionView, Object newValue, Boolean isASubPropertyChange)
   σε MS.Internal.Data.ClrBindingWorker.OnSourcePropertyChanged(Object o, String propName)
   σε MS.Internal.Data.PropertyPathWorker.OnPropertyChanged(Object sender, PropertyChangedEventArgs e)
   σε System.Windows.WeakEventManager.ListenerList`1.DeliverEvent(Object sender, EventArgs e, Type managerType)
   σε System.ComponentModel.PropertyChangedEventManager.OnPropertyChanged(Object sender, PropertyChangedEventArgs args)
   σε ObservableObject.OnPropertyChanged(String propertyName) στο C:\Users\treej\Source\Repos\FiloFix\FiloFix\Helper Classes\ObservableObject.cs:γραμμή 24
   σε FiloFix.ViewModel.NoteViewModel.set_IsOpen(Boolean value) στο C:\Users\treej\Source\Repos\FiloFix\FiloFix\ViewModel\NoteViewModel.cs:γραμμή 113
   σε FiloFix.ViewModel.NoteViewModel.SearchNote() στο C:\Users\treej\Source\Repos\FiloFix\FiloFix\ViewModel\NoteViewModel.cs:γραμμή 50
   σε FiloFix.ViewModel.NoteViewModel.<get_SearchNoteCommand>b__8_1(Object p) στο C:\Users\treej\Source\Repos\FiloFix\FiloFix\ViewModel\NoteViewModel.cs:γραμμή 35
   σε RelayCommand.Execute(Object parameter) στο C:\Users\treej\Source\Repos\FiloFix\FiloFix\Helper Classes\RelayCommand.cs:γραμμή 28
   σε MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated)
   σε System.Windows.Controls.Primitives.ButtonBase.OnClick()
   σε System.Windows.Controls.Button.OnClick()
   σε System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
   σε System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
   σε System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   σε System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   σε System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   σε System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   σε System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
   σε System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
   σε System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   σε System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   σε System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   σε System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   σε System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   σε System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
   σε System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
   σε System.Windows.Input.InputManager.ProcessStagingArea()
   σε System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   σε System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
   σε System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
   σε System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   σε System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   σε MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   σε MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   σε System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   σε System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   σε System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   σε MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   σε MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   σε System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   σε System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   σε System.Windows.Application.RunDispa...

有什么想法吗?提前致谢

1 个答案:

答案 0 :(得分:1)

尝试以下

public bool SearchNotes(NoteModel CurrentNote, string sSearch)
    {
        //check the open connection
        if (ConnectData.OpenConnection() == true)
        {
            try
            {
                string SQLSearch = "select note_id, date, time, note from note where date like '%" + sSearch + "%' or time like '%" + sSearch + "%' or note like '%" + sSearch + "%' group by note_id, date, time, note";

                //get the phone types for lookups
                SqlCommand cmdSearchNotes = new SqlCommand(SQLSearch, ConnectData.connection);
                SqlDataReader drSearchResults = cmdSearchNotes.ExecuteReader();

                // CHANGE IS HERE !!!!!!!!!!!!!!!!
                var list = new List<NoteModel.SearchResult>();

                while (drSearchResults.Read())
                {
                    CurrentNote.SearchResults.Add(new NoteModel.SearchResult()
                    {
                        NoteID = (int)drSearchResults["note_id"],
                        Date = drSearchResults["date"].ToString(),
                        Time = drSearchResults["time"].ToString(),
                        Note = (string)drSearchResults["note"]
                    });
                }

                // CHANGE IS HERE !!!!!!!!!!!!!!!! 
                CurrentNote.SearchResults = list;
                drSearchResults.Dispose();
                cmdSearchNotes.Dispose();

                //close Connection
                ConnectData.CloseConnection();

                return true;
            }
            catch (SqlException ex)
            {
                return false;
                throw new ApplicationException("Something went wrong with fetching the note search results: ", ex);
            }
        }
        //connection failed
        else
        {
            return false;
        }
    }

注意我只在列表填满后指定 CurrentNote.SearchResults 。弹出窗口第一次打开时会绑定到列表。下次单击弹出窗口时已经绑定,并且当您调用

CurrentNote.SearchResults = ...

某些操作发生在WPF中。然后你去改变那个列表的内容,这就是导致错误的原因。