绑定到List的ListBox未更新

时间:2014-02-23 20:15:26

标签: c# wpf xaml listbox

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

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));
        }
    }
}

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>

Window C#代码:

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();
    }
}

1 个答案:

答案 0 :(得分:3)

  

是的,数据结构必须是一个列表,而不是一个ObservableCollection(但如果需要,我可以构建一个包装器或其他东西)

非常简单,ListBox用户界面(Xaml)更新完全基于少数几个接口,例如INotifyPropertyChangedINotifyCollectionChanged以及更多

当他们持有的项目被添加/删除/刷新时,这些界面会指示用户界面...

List没有实现这些接口(它实现IEnumerableICollection ......等内容。因此,将ListBox.ItemsSource绑定到List类型的集合并不会让您在UI中使用ObservableCollection更新。

当然,如果您被迫使用List并且不介意如何实现结果,那么每次从List移除项目时,请重置窗口{ {1}}(在删除之前将DataContext设置为DataContext,并在删除之后再设置为null。然而,如果有人强迫你不得不这样做,那就太疯狂了,你应该多跟他们聊聊并解释为什么它会疯了。

至于你的包装器的想法,确保你可以建立自己的自定义集合,说明实现dataIEnumerableINotifyCollectionChanged并在内部持有INotifyPropertyChanged或其他什么,但是你的List应该属于这种类型的包装器以获得更新行为。

你还没有提到为什么你被迫不使用ListBox.ItemSource,但是如果你可以使用它而不是为了简单的东西发明你自己的自定义集合。