ItemsSource更改时如何更新ListBox

时间:2018-05-14 08:36:58

标签: c# wpf mvvm

我有按钮“ADD”和“DEL”,但“DEL”不起作用。有什么问题?

我的ObservableCollection<User>中的

计数已更改,但ListBox不是

示例项目:https://github.com/Veselov-Dmitry/MyQuestion

视图:

<StackPanel>
    <Button Content="ADD"
            Command="{Binding AddUsers_OASUCommand}"
            CommandParameter="">
    </Button>
    <ListBox ItemsSource="{Binding Users_OASU}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <WrapPanel>
                    <TextBlock Text="{Binding Name}" />
                    <TextBlock Text="{Binding Login}" />
                    <Button Content="DEL"
                            Command="{Binding DelUsers_OASUCommand}"
                            CommandParameter="{Binding Path=Content,                                                     
                                RelativeSource={RelativeSource Mode=FindAncestor , 
                                    AncestorType={x:Type ListBoxItem}}}">
                        <Button.DataContext>
                            <local:ViewModel />
                        </Button.DataContext>
                    </Button>
                </WrapPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</StackPanel>

我在构造函数MainView中设置了datacontext

viewvmodel:

class ViewModel
{
    public event PropertyChangedEventHandler PropertyChanged;

    public ObservableCollection<User> Users_OASU{get; set;}                
    public ICommand AddUsers_OASUCommand{get; set;} 
    public ICommand DelUsers_OASUCommand{get; set;} 

    public ViewModel()
    {
        Users_OASU = new ObservableCollection<User>(GetUsers());

        AddUsers_OASUCommand = new Command<object>(arg => AddUsers_OASUMethod());
        DelUsers_OASUCommand = new Command<object>(arg => DelUsers_OASUMethod(arg));
    }

    private void DelUsers_OASUMethod(object arg)
    {
        User find = Users_OASU.Where(x => x.Login == (arg as User).Login).FirstOrDefault();
        Users_OASU.Remove(find);
    }

    private void AddUsers_OASUMethod()
    {
        Users_OASU.Add(new User("52221", "John X."));
    }

    private List<User> GetUsers()
    {
        List<User> list = new List<User>();
        list.Add(new User("52222", "John W."));
        list.Add(new User("52223", "John Z."));
        list.Add(new User("52224", "John A."));
        list.Add(new User("52225", "John M."));
        return list;
    }
}

1 个答案:

答案 0 :(得分:1)

&#34;我的ObservableCollection中的count已更改,但ListBox没有&#34; - 您有多个ViewModel实例,计数已更改,但未显示在显示的集合中

您需要正确设置DataTemplate以避免

首先,每个Button都将获得DataContext的User对象(它将由ItemsSource中的ListBox提供)。您不能声明新的<Button.DataContext>

第二,DelUsers_OASUCommand在ViewModel类中声明,可以在ListBox级别从DataContext访问。相应地更改绑定路径。

<DataTemplate>
    <WrapPanel>
        <TextBlock Text="{Binding Name}" />
        <TextBlock Text="{Binding Login}" />
        <Button Command="{Binding DataContext.DelUsers_OASUCommand,
                          RelativeSource={RelativeSource AncestorType=ListBox}}"
                CommandParameter="{Binding Path=Content, 
                RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}"
                Content="DEL" />
    </WrapPanel>
</DataTemplate>

另外我会更改DelUsers_OASUMethod以接受用户作为参数

private void DelUsers_OASUMethod(object arg)
{
    Users_OASU.Remove(arg as User);
}

并传递CommandParameter,如下所示:

CommandParameter="{Binding Path=.}"

或相同,但更短:

CommandParameter="{Binding}"