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

时间:2012-06-18 18:47:05

标签: c# wpf xml listview multiple-columns

我是Binding和WPF的新手我最近学会了如何使用Binding tech创建一个包含多个列的listBox

 <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>

这是代码:

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

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

 listBoxSS.Items.Clear();

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

修改

<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>

这是代码:

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

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

 listBoxPE.ItemsSource = employees;
        Gemployees = employees;

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

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

每当我从Gemployees添加或删除项目时,ListView都会执行刷新!很酷,但仍然有点努力绑定。现在我正在为每个ListView做一个接口类,所以我可以把我的东西放进去。它在添加项目时不会有任何灵活性。

10 个答案:

答案 0 :(得分:28)

您将ItemsSource绑定到名为DataContext的{​​{1}}中的属性,因此要更新集合,您需要转到Items中的Items属性DataContext并清除它。

此外,如果您希望在基础集合发生更改时更新UI,则Items属性必须是ObservableCollection类型,而不是List

不需要在代码中设置ItemsSource的代码,应该将其删除。您只需将ItemsSource设置在一个位置,而不是两者。

以下是一个如何运作的简单示例:

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

public MyConstructor()
{
    ...

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

现在你有:

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

您将ItemsSource绑定到ObservableCollection<Student>,当您要清除列表时,您可以致电:

Students.Clear()

答案 1 :(得分:13)

奇怪但是真实:我的XAML文件中的以下错误击键产生了错误&#34;当使用ItemsSource时,操作无效。使用ItemsControl.ItemsSource访问和修改元素。&#34;:

</ItemsControl.ItemTemplate>x`

注意&#34; x`&#34;关闭元素标记之后的字符。

答案 2 :(得分:10)

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

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

我真诚地希望这有助于某人。

答案 3 :(得分:3)

您需要处理与ItemsSource数据绑定的集合。为了获取集合更改通知(添加或删除项目时),您应该使用ObservableCollection<T>

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

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

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

答案 4 :(得分:3)

我认识的派对来晚了,但我认为这个答案在上面并不十分清楚。它与流氓角色相关,但这也导致例外:

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

当你的意思是:

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

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

答案 5 :(得分:1)

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

答案 6 :(得分:1)

始终将ItemsSource绑定到ObservableCollection以避免内存泄漏。 ObservableCollection也将导致显示通过添加/删除自动更新。在了解这一点之前,我总是绑定到数组。

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

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

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

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

答案 7 :(得分:0)

我遇到了同样的问题,我最终意识到我正在尝试将新项目直接添加到控件的ItemsSource,而不是添加到作为ItemsSource的ObservableCollection。

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

答案 8 :(得分:0)

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

我所拥有的:

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

我应该拥有的东西:

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

答案 9 :(得分:0)

对我来说,这是完全无关的问题。这是一个愚蠢的语法错误,我忘了用select * from tableA_with_joins包装<style> </style>

感谢Microsoft提供完全令人困惑的错误消息。