WPF:PropertyChanged(似乎是)创建一个(无限)循环

时间:2015-09-23 01:26:17

标签: c# wpf listview mvvm

使用MVVMListView编辑属性时,我收到“堆栈溢出”-Exception

我的ViewModel实现了INotifyPropertyChanged

我正在制作'日历'。在这个'日历'的每一天,我可以访问两个文件,具体取决于我当前正在查看的那天,这两个文件在我的ViewModel中被转换为两个字符串列表,一个是'Schedule'而另一个是是'笔记'。它们都存储在UI上的ListViews中。

用户可以选择添加删除修改项目。用户可以选择他/她想要的动作,并将其存储在名为SelectedEditingAction的属性中。

我的SelectedSchedule的{​​{1}}和SelectedNote分别与ViewModelSchedule ListView的所选项目相关联

当用户在ListView上选择一个项目时,相应的SelectedItem属性会发生变化。

  • 如果它的值不是-1,则调用方法Notes,传递ActivateEditingActions
  • 如果是附表(布尔):

    • selected value (int)ActivateEditingAction属性调用false。
    • SelectedNoteActivateEditingAction属性调用true。

SelectedNote Property:

SelectedSchedule

ActivateEditingAction

    public int SelectedNote
    {
        get
        {
            return -1;
        }
        set
        {
            if (value != -1) 
                ActivateEditingAction(false, value);
            // I don't set to an underlying field here,
            // I always want this to be -1, but I can 
            // pass in the value to ActivateEditingAction 
            // that the ListView WANTS me to set to a field

            // - Not sure if this is bad code practice
        }
    }

而且,我正在处理的方法(我之后正在进行EditSelectedItemInListView)

    private void ActivateEditingAction(bool isSchedule, int selectedItem)
    {
        if (SelectedEditingAction == "Nothing")
            return;

        switch (SelectedEditingAction)
        {
            case "Add Items": AddItemToListView(isSchedule); break;
            case "Remove Items": RemoveSelectedItemFromListView(isSchedule, selectedItem); break;
            case "Edit Items": EditSelectedItemInListView(isSchedule, selectedItem); break;
            default: throw new NotImplementedException();
        }

        base.OnPropertyChanged(isSchedule ? "Schedule" : "Notes");
    }

删除和添加似乎工作正常。 但是我在编辑时遇到了堆栈溢出。

当我选择了添加编辑操作后,将项目添加到所选列表视图中,完成后再返回 private void AddItemToListView(bool isSchedule) { // Getting the new item string newItem = isSchedule ? "You have no schedule for this day." : "You have no notes for this day."; // Mutation if (isSchedule) _schedule.Add(newItem); else _notes.Add(newItem); } private void RemoveSelectedItemFromListView(bool isSchedule, int selectedItem) { // Confirming the action var confirm = MessageBox.Show("Are you sure you want to remove this item?", "", MessageBoxButton.YesNo, MessageBoxImage.Question); if (confirm != MessageBoxResult.Yes) return; // Mutation if (isSchedule) _schedule.RemoveAt(selectedItem); else _notes.RemoveAt(selectedItem); // If the ListView doesn't have any more items, we don't want it to be empty! if ((isSchedule ? _schedule : _notes).Count == 0) AddItemToListView(isSchedule); } ,最后我调用{{1} } 然后它进入无限循环,导致堆栈溢出。

所以基本上,我认为发生了什么(出于某种原因)是当我通知属性发生变化时,ListView(这里显示的是Schedule ListView)

ActivatateEditingAction

更新ItemsSource,导致(逻辑上)SelectedIndex重置为0,从而将SelectedIndex属性设置为0,调用base.OnPropertyChanged(isSchedule ? "Schedule" : "Notes");方法(并继续反复执行),结果为{ {3}}

似乎项目不断添加,然后它会通知属性它已被更改,因此这是一个问题。

我还有一些与删除操作有关的问题。它工作正常 - 直到PropertyChanged出现奇怪的事情。

我可以删除所有这些项目this call stack and a stack over flow exception(即附表列表)

当我从屏幕截图 ee 中找到最后一项时,删除它就可以正常工作,制作出类似的新副本。 删除操作会添加一个新项目“您今天没有时间表”。当集合的计数为0或更低时(我发现<ListView ItemsSource="{Binding Schedule}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Margin="0,5,0,0" Background="Transparent" BorderThickness="0" Grid.Row="1" SelectedIndex="{Binding SelectedSchedule}" ItemContainerStyle="{StaticResource ListViewItemContainerStyle}"> <ListBox.ItemTemplate> <HierarchicalDataTemplate> <WrapPanel Orientation="Horizontal"> <TextBlock FontSize="15" TextWrapping="Wrap" Text="{Binding}"/> </WrapPanel> </HierarchicalDataTemplate> </ListBox.ItemTemplate> </ListView> 在这里有效而不是从ActivateEditingAction调用的时候发现很奇怪)

新的自动生成的项目将添加到相应的列表中,但随后它将停止工作。当我从ListView中删除此项时,然后,像添加项方法一样,它到达base.OnPropertyChanged(),再次调用它,然后当它完成时 - 他再次在PropertyChanged方法中调用它,这发生在结束(这次它不会导致Stack Over Flow,因为如果您确定要执行删除操作,它会在每次询问时暂停)。

我也想请你注意,这些无限循环只发生在我删除了gyazo截图中的所有项目并在Listview中获得一个新项目(“你今天没有时间表。”)之后。当我删除可以在gyazo屏幕截图中看到的最后一项时,不会发生这种情况。 这很奇怪。

为什么在更新值或删除上次自动添加的项目时会进入无限循环?

0 个答案:

没有答案