C# 绑定到列表的列表框未更新

C# 绑定到列表的列表框未更新,c#,wpf,xaml,listbox,C#,Wpf,Xaml,Listbox,这是演示该问题的最简单的程序示例。我需要将列表绑定到列表框。是的,数据结构必须是一个列表,而不是一个ObservableCollection(但如果需要,我可以构建一个包装器或其他东西)。 该程序中有一个列表框和一个按钮,用于删除列表中的第一项。但是当删除该项时,即使配置了单向绑定,列表框内容也不会更新。我需要它来更新项目删除 class Data: INotifyPropertyChanged { public event PropertyChangedEventHandler Pro

这是演示该问题的最简单的程序示例。我需要将列表绑定到列表框。是的,数据结构必须是一个列表,而不是一个ObservableCollection(但如果需要,我可以构建一个包装器或其他东西)。 该程序中有一个列表框和一个按钮,用于删除列表中的第一项。但是当删除该项时,即使配置了单向绑定,列表框内容也不会更新。我需要它来更新项目删除

class Data: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private List<string> items;
    public List<string> Items { get { return items; } }

    public Data(List<string> items)
    {
        this.items = items;
    }

    public void RemoveFirstItem()
    {
        items.Remove(items[0]);
        RaisePropertyChanged("Items");
    }

    private void RaisePropertyChanged(string p)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(p));
        }
    }
}
类数据:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
私人清单项目;
公共列表项{get{return Items;}}
公共数据(列表项)
{
这个项目=项目;
}
public void RemoveFirstItem()
{
项目。删除(项目[0]);
增加财产变更(“项目”);
}
私有void raiseProperty已更改(字符串p)
{
if(PropertyChanged!=null)
{
房地产变更(这是新的房地产变更发展(p));
}
}
}
XAML代码:

<Window x:Class="ListBoxTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListBox Name="TheListBox" Margin="0,0,0.138,46.231" ItemsSource="{Binding Path=Items, Mode=OneWay}"/>
        <Button Content="Button" HorizontalAlignment="Left" Margin="212,292,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
    </Grid>
</Window>

窗口C#代码:

公共部分类主窗口:窗口
{
私人数据;
公共主窗口()
{
初始化组件();
数据=新数据(新列表{“1”、“2”、“3”、“4”});
this.DataContext=数据;
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
data.RemoveFirstItem();
}
}
是的,数据结构必须是一个列表,而不是一个可观察的集合(但如果需要,我可以构建一个包装器或其他东西)

这非常简单,
ListBox
UI(Xaml)更新都是基于一些接口,例如,以及其他一些接口

这些接口在它们所持有的项目被添加/删除/刷新时指示UI

列表
不实现这些接口(它实现诸如
IEnumerable
ICollection
…)。因此,将您的
ListBox.ItemsSource
绑定到类型为
List
的集合不会让您获得在UI中使用带有更新的
可观察集合的好处

当然,如果您被迫使用
列表
,并且不介意如何获得结果,那么每次您从
列表
中删除项目时,都要重置窗口的
数据上下文
(在删除之前将
数据上下文
设置为
,在删除之后再次设置为
数据
)。然而,如果有人强迫你这么做,这简直是疯了,你应该和他们聊一聊,解释为什么这是疯了

至于包装器的想法,请确保您可以构建自己的自定义集合,比如实现
IEnumerable
INotifyCollectionChanged
INotifyPropertyChanged
,并在内部保存一个
列表
或其他内容,但是您的
ListBox.ItemSource
应该是这种类型的包装器,以获取更新行为

您还没有提到为什么您被迫不使用
可观察集合
,但是如果可以,您应该直接使用它,而不是为简单的东西创建自己的自定义集合

public partial class MainWindow : Window
{
    private Data data;
    public MainWindow()
    {
        InitializeComponent();
        data = new Data(new List<string>{ "1", "2", "3", "4" });
        this.DataContext = data;

    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        data.RemoveFirstItem();
    }
}