C# 使用 ItemsSource 时操作无效。改为使用 ItemsControl.ItemsSource 访问和修改元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11089104/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 16:26:01  来源:igfitidea点击:

Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead

c#wpfxmllistviewmultiple-columns

提问by Yasser

I am new in Binding and WPF recently I've learned how to create a listBoxwith multiple columns using Binding tech

我最近刚接触 Binding 和 WPF 我已经学会了如何listBox使用 Binding 技术创建具有多个列的

 <ListView ItemsSource="{Binding Items}" Margin="306,70,22,17" MouseDoubleClick="listBoxSS_MouseDoubleClick" Name="listBoxSS" >           
    <ListView.View>
            <GridView>
                <GridView.Columns>
                    <GridViewColumn Header="first_name " Width="100" DisplayMemberBinding="{Binding Path=First_name}" />
                    <GridViewColumn Header="last_name" Width="100" DisplayMemberBinding="{Binding Path=Last_name}" />
                    <GridViewColumn Header="phone_number" Width="100" DisplayMemberBinding="{Binding Path=Phones[0]}" />
                    <GridViewColumn Header="notes" Width="100" DisplayMemberBinding="{Binding Path=Notes}" />
                </GridView.Columns>
            </GridView>
        </ListView.View>
    </ListView>

and this is the code:

这是代码:

List<Student> arr = search.students();
        listBoxSS.ItemsSource = arr;

but the problem was when I tried to use add or remove item or clear

但问题是当我尝试使用添加或删除项目或清除时

 listBoxSS.Items.Clear();

Please I need an example for using the items source or the way that I can ADD or Remove Item or Clear the list.

请我需要一个示例来使用项目源或我可以添加或删除项目或清除列表的方式。

EDIT:

编辑:

<ListView ItemsSource="{Binding Items}" Margin="306,70,22,17" MouseDoubleClick="listBoxSS_MouseDoubleClick" Name="listBoxSS" >
    <ListView.View>
        <GridView>
            <GridView.Columns>
                <GridViewColumn Header="first_name " Width="100" DisplayMemberBinding="{Binding Path=First_name}" />
                <GridViewColumn Header="last_name" Width="100" DisplayMemberBinding="{Binding Path=Last_name}" />
                <GridViewColumn Header="phone_number" Width="100" DisplayMemberBinding="{Binding Path=Phones[0]}" />
                <GridViewColumn Header="notes" Width="100" DisplayMemberBinding="{Binding Path=Notes}" />
            </GridView.Columns>
        </GridView>
    </ListView.View>
</ListView>

and here is the code:

这是代码:

 ObservableCollection<Employee> Gemployees;
var employees = new ObservableCollection<Employee>(search.employees());

search.employees()get the list of all employees in my DB

search.employees()获取我的数据库中所有员工的列表

 listBoxPE.ItemsSource = employees;
        Gemployees = employees;

now I can perform all the methods on Gemployees

现在我可以对 Gemployees 执行所有方法

 Gemployees.Remove((Student)listBoxSS.SelectedItem);
 Gemployees.Add((Student)listBoxSS.SelectedItem);

The ListViewperform a refresh whenever I add or remove an Item from Gemployees!! Cool but still a little hard work on binding. Now I am doing an interface class to every ListView so I can put my stuff into it. It wont perform any flexibility in Adding Items.

ListView每当我添加或删除Gemployees的项目进行刷新!很酷,但在绑定方面仍然有点困难。现在我正在为每个 ListView 做一个接口类,这样我就可以把我的东西放进去。它不会在添加项目方面表现出任何灵活性。

采纳答案by Rachel

You're binding the ItemsSourceto a property in the DataContextcalled Items, so to update the collection, you need to go to the Itemsproperty in the DataContextand clear it.

您将 绑定ItemsSource到被DataContext调用的属性Items,因此要更新集合,您需要转到 中的Items属性DataContext并清除它。

In addition, the Itemsproperty needs to be of type ObservableCollection, not Listif you want it to update the UI whenever the underlying collection changes.

此外,Items属性需要是 type ObservableCollection,而不是List如果您希望它在底层集合更改时更新 UI。

Your bit of code that sets the ItemsSourcein the code behind is not needed and should be removed. You only need to set the ItemsSourcein one place, not both.

ItemsSource在后面的代码中设置的代码位是不需要的,应该删除。你只需要ItemsSource在一个地方设置,而不是两个。

Here's a simple example of how it can work:

这是它如何工作的一个简单示例:

// Using Students instead of Items for the PropertyName to clarify
public ObservableCollection<Student> Students { get; set; }

public MyConstructor()
{
    ...

    Students = search.students();
    listBoxSS.DataContext = this;
}

Now when you have:

现在当你有:

<ListView ItemsSource="{Binding Students}" ... />

you're binding the ItemsSourceto the ObservableCollection<Student>, and when you want to clear the list you can call:

您将 绑定ItemsSourceObservableCollection<Student>,当您想清除列表时,您可以调用:

Students.Clear()

回答by Josh

Assign the ItemsSource property of the listbox to a public property inside the form's class. Then try adding a removing from that, calling PropertyChanged inside the setter, instead of calling clear directly on the listbox items source.

将列表框的 ItemsSource 属性分配给表单类中的公共属性。然后尝试从中添加一个删除,在 setter 中调用 PropertyChanged,而不是直接在列表框项目源上调用 clear。

回答by Douglas

You need to work against the collection that is data-bound to your ItemsSource. In order to get collection change notifications (when items get added or removed), you should use an ObservableCollection<T>:

您需要针对数据绑定到您的ItemsSource. 为了获得集合更改通知(添加或删除项目时),您应该使用ObservableCollection<T>

var students = new ObservableCollection<Student>(search.students());
listBoxSS.ItemsSource = students;

students.Clear();
students.Add(new Student("ABC"));

And you should remove the ItemsSource="{Binding Items}"declaration from your XAML.

您应该ItemsSource="{Binding Items}"从 XAML 中删除声明。

回答by Travis

I had this same problem, and I eventually realized that I was trying to add a new item directly to the control's ItemsSource, rather than to the ObservableCollection that served as the ItemsSource.

我遇到了同样的问题,我最终意识到我试图将一个新项目直接添加到控件的 ItemsSource,而不是添加到充当 ItemsSource 的 ObservableCollection。

I figured I'd post this, as it might help other novice wpfers.

我想我会发布这个,因为它可能会帮助其他新手 wpfers。

回答by Matthijs H

I know this question has been answered about 2 years ago, however I had this problem myself as well and thought of a possible solution myself, which works. Maybe this doesn't work in certain scenarios and maybe I'm simply not seeing something, but it worked for me so I'm sharing it here:

我知道这个问题已经在大约 2 年前得到了回答,但是我自己也遇到了这个问题,并且我自己想到了一个可行的解决方案。也许这在某些情况下不起作用,也许我只是没有看到某些东西,但它对我有用,所以我在这里分享:

listView.ClearValue(ItemsControl.ItemsSourceProperty);
listView.ItemsSource = NewSource;

I sincerely hope this helps someone.

我真诚地希望这对某人有所帮助。

回答by Brett

Weird but true: the following errant keystrokes in my XAML file produced the error "Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead.":

奇怪但真实:我的 XAML 文件中的以下错误击键产生了错误“在使用 ItemsSource 时操作无效。改为使用 ItemsControl.ItemsSource 访问和修改元素。”:

</ItemsControl.ItemTemplate>x`

Note the "x`" characters after the closing element tag.

请注意结束元素标记后的“x`”字符。

回答by Tim Rutter

Late to the party I know but I think this answer isn't quite clear above. Its related to the rogue characters post, but this also causes the exception:

我知道聚会迟到了,但我认为上面的答案并不十分清楚。它与流氓角色帖子有关,但这也会导致异常:

<ItemsControl ItemsSource="{Binding AnObservableCollection}">
    <Label Content="{Binding Name}"/>
</ItemsControl>

When what you meant was:

当你的意思是:

<ItemsControl ItemsSource="{Binding AnObservableCollection}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Label Content="{Binding Name}"/>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Its easy as a newcomer (or before first morning coffee) to think the first is correct and the exception in no way explains what is wrong.

作为新人(或在第一次早上喝咖啡之前)很容易认为第一个是正确的,而例外绝不能解释什么是错误的。

回答by Arc2066

I had the same error message appear, resulting from a syntax error. It turns out I was accidentally defining an item in a TreeViewthat had an ItemsSourcedefined. I had defined a DataTemplatefor the tree view, but accidentally put it directly in <TreeView>instead of <TreeView.Resources>, causing the error.

由于语法错误,我出现了相同的错误消息。事实证明,我不小心在 aTreeView中定义了一个已定义的项目ItemsSource。我已经DataTemplate为树视图定义了 a ,但不小心将其直接放入<TreeView>而不是<TreeView.Resources>,导致错误。

What I had:

我有什么:

<TreeView ItemSource ="{Binding Items}">
  <HierarchicalDataTemplate> ... </HierarchicalDataTemplate>
  <DataTemplate> ... </DataTemplate>
</TreeView>

What I should have had:

我应该有的:

<TreeView ItemSource ="{Binding Items}">
  <TreeView.Resources>
    <HierarchicalDataTemplate> ... </HierarchicalDataTemplate>
    <DataTemplate> ... </DataTemplate>
  </TreeView.Resources>
</TreeView>

回答by CBFT

Always bind an ItemsSource to an ObservableCollection to avoid memory leaks. An ObservableCollection will also cause the display to update automatically with Add/Remove. I used to always bind to arrays before I learned this.

始终将 ItemsSource 绑定到 ObservableCollection 以避免内存泄漏。ObservableCollection 也会使显示通过添加/删除自动更新。在我学会这个之前,我曾经总是绑定到数组。

A useful source: https://onewindowsdev.com/2016/09/22/a-memory-leak-may-occur-when-you-use-data-binding-in-windows-presentation-foundation/

一个有用的来源:https: //onewindowsdev.com/2016/09/22/a-memory-leak-may-occur-when-you-use-data-binding-in-windows-presentation-foundation/

1) For DataBinding in general the class you bind to should implement INotifyPropertyChanged. The exception to this is to use Mode=OneTime bindings.

1) 对于 DataBinding,您绑定到的类通常应该实现 INotifyPropertyChanged。对此的例外是使用 Mode=OneTime 绑定。

2) An ItemsSource should always be a class that implements INotifyCollectionChange. The easiest way to do this is to use an ObservableCollection. ObservableCollection does have a constructor that takes in an IEnumerable which I've found useful.

2) ItemsSource 应始终是实现 INotifyCollectionChange 的类。最简单的方法是使用 ObservableCollection。ObservableCollection 确实有一个构造函数,它接受一个我发现有用的 IEnumerable。

3) If the ItemsControl is an ObservableCollection < SomeClass > than SomeClass should implement INotifyPropertyChange. You can then safely bind to individual properties of SomeClass.

3) 如果 ItemsControl 是 ObservableCollection < SomeClass > 则 SomeClass 应该实现 INotifyPropertyChange。然后,您可以安全地绑定到 SomeClass 的各个属性。