可观察集合列表框中没有更新

发布于 2024-12-06 13:27:08 字数 3466 浏览 0 评论 0原文

我有一个绑定到 Observablecollection 的 Silverlight 列表框,它显示得很好(第一次),但是当我尝试通过后面的代码更新它时,更改不会反映在 UI 中。我用过MVVM模式。请查看视图和视图模型。

<UserControl x:Class="GridOperations.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:GridOperations.ViewModel"
    mc:Ignorable="d"
    d:DesignHeight="700" d:DesignWidth="700">
    <UserControl.DataContext>
        <local:ShowUserListViewModel/>
    </UserControl.DataContext>
    <UserControl.Resources>
        <local:ShowUserListViewModel x:Key="viewModelKey"/>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="White">

        <ListBox VerticalAlignment="Top" Margin="0,20,0,0" x:Name="lstBox" ItemsSource="{Binding UserList}" Width="700" Height="150" Background="AliceBlue">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="300"/>
                            <ColumnDefinition Width="100"/>
                            <ColumnDefinition Width="100"/>
                            <ColumnDefinition Width="100"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Margin="30,0,0,0" Text="{Binding UserId}" HorizontalAlignment="Left"/>
                        <TextBlock Margin="30,0,0,0" Text="{Binding Path=UserName, Mode=TwoWay}" Grid.Column="1" HorizontalAlignment="Left"/>
                        <Button Margin="30,0,0,0" Grid.Column="2" Content="Edit" Height="20" HorizontalAlignment="Left" Command="{Binding Source={StaticResource viewModelKey}, Path=UpdateUserCommand}" />
                        <Button Margin="10,0,0,0" Grid.Column="3" Content="Del" Height="20" HorizontalAlignment="Left" />
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

    </Grid>
</UserControl>


    public class ShowUserListViewModel : INotifyPropertyChanged
        {
            public ShowUserListViewModel()
            {
                mUserList = new ObservableCollection<User>();
                mUserList.Add(new User() { UserId = Guid.NewGuid().ToString(), UserName = "testuser1", IsAdmin = true });
                mUserList.Add(new User() { UserId = Guid.NewGuid().ToString(), UserName = "testuser2", IsAdmin = true });

                this.UpdateUserCommand = new DelegateCommand(this.UpdateUser);

            }

            public ICommand UpdateUserCommand { get; private set; }

            private ObservableCollection<User> mUserList;
            public ObservableCollection<User> UserList
            {
                get
                {
                    return mUserList;
                }
            }

            public event PropertyChangedEventHandler PropertyChanged;

            private void UpdateUser()
            {
                this.UserList.Add(new User() { UserId = Guid.NewGuid().ToString(), UserName = "test", IsAdmin = false });            
            }
        }

I have a Silverlight Listbox bound to Observablecollection which shows up fine (first time) but when I try to update it through the code behind, the change does not reflect in UI. I have used MVVM pattern . Pl have a look and at view and viewmodel.

<UserControl x:Class="GridOperations.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:GridOperations.ViewModel"
    mc:Ignorable="d"
    d:DesignHeight="700" d:DesignWidth="700">
    <UserControl.DataContext>
        <local:ShowUserListViewModel/>
    </UserControl.DataContext>
    <UserControl.Resources>
        <local:ShowUserListViewModel x:Key="viewModelKey"/>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="White">

        <ListBox VerticalAlignment="Top" Margin="0,20,0,0" x:Name="lstBox" ItemsSource="{Binding UserList}" Width="700" Height="150" Background="AliceBlue">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="300"/>
                            <ColumnDefinition Width="100"/>
                            <ColumnDefinition Width="100"/>
                            <ColumnDefinition Width="100"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Margin="30,0,0,0" Text="{Binding UserId}" HorizontalAlignment="Left"/>
                        <TextBlock Margin="30,0,0,0" Text="{Binding Path=UserName, Mode=TwoWay}" Grid.Column="1" HorizontalAlignment="Left"/>
                        <Button Margin="30,0,0,0" Grid.Column="2" Content="Edit" Height="20" HorizontalAlignment="Left" Command="{Binding Source={StaticResource viewModelKey}, Path=UpdateUserCommand}" />
                        <Button Margin="10,0,0,0" Grid.Column="3" Content="Del" Height="20" HorizontalAlignment="Left" />
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

    </Grid>
</UserControl>


    public class ShowUserListViewModel : INotifyPropertyChanged
        {
            public ShowUserListViewModel()
            {
                mUserList = new ObservableCollection<User>();
                mUserList.Add(new User() { UserId = Guid.NewGuid().ToString(), UserName = "testuser1", IsAdmin = true });
                mUserList.Add(new User() { UserId = Guid.NewGuid().ToString(), UserName = "testuser2", IsAdmin = true });

                this.UpdateUserCommand = new DelegateCommand(this.UpdateUser);

            }

            public ICommand UpdateUserCommand { get; private set; }

            private ObservableCollection<User> mUserList;
            public ObservableCollection<User> UserList
            {
                get
                {
                    return mUserList;
                }
            }

            public event PropertyChangedEventHandler PropertyChanged;

            private void UpdateUser()
            {
                this.UserList.Add(new User() { UserId = Guid.NewGuid().ToString(), UserName = "test", IsAdmin = false });            
            }
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

习ぎ惯性依靠 2024-12-13 13:27:08

首先,您应该避免将集合属性设置为可写。 IE,替换此代码:

    private ObservableCollection<User> mUsers = new ObservableCollection<User>();
    public ObservableCollection<User> Users
    {
        get
        {
            return mUsers;
        }
        set
        {
            mUsers = value;
            RaisePropertyChangedEvent("Users");
        }
    }

通过此代码:

    private ObservableCollection<User> mUsers = new ObservableCollection<User>();
    public ObservableCollection<User> Users
    {
        get
        {
            return mUsers;
        }

    }

然后,当您将项目添加到集合中时,您不必告诉集合已更改(集合属性本身没有更改),但这是该集合的责任集合本身(通过 INotifyCollectionChanged):

因此,“onclick”方法可以简单地像这样:

 private void OnClick(User userInstanceToEdit)
    {
        this.Users.Add(new User() { UserId = Guid.NewGuid().ToString(), UserName = "test", IsAdmin = false });         

    }

最后,我将用此方法替换 ListBox.ItemsSource 声明,因为不需要两种方法:

 <ListBox x:Name="lstBox" ItemsSource="{Binding Users}" 

Firstly, you should avoid putting a collection property writable. IE, replace this code :

    private ObservableCollection<User> mUsers = new ObservableCollection<User>();
    public ObservableCollection<User> Users
    {
        get
        {
            return mUsers;
        }
        set
        {
            mUsers = value;
            RaisePropertyChangedEvent("Users");
        }
    }

by this code :

    private ObservableCollection<User> mUsers = new ObservableCollection<User>();
    public ObservableCollection<User> Users
    {
        get
        {
            return mUsers;
        }

    }

Then, when you add an item to the collection, you don't have to tell the collection has changed (the collection property hasn't changed in itself), but it's the responsibility of the collection itself (via INotifyCollectionChanged) :

So, the "onclick" method can be simply like this:

 private void OnClick(User userInstanceToEdit)
    {
        this.Users.Add(new User() { UserId = Guid.NewGuid().ToString(), UserName = "test", IsAdmin = false });         

    }

Finally, I would replace the ListBox.ItemsSource declaration with this one, as two ways is not required :

 <ListBox x:Name="lstBox" ItemsSource="{Binding Users}" 
古镇旧梦 2024-12-13 13:27:08

从这篇文章中得到了提示 Stackoverflow

基本上我需要将 Datacontext 与 Listbox 控件一起使用(即使在 UserControl 级别设置 Datacontext 之后)。唯一需要更改的行是:

<ListBox x:Name="lstBox" ItemsSource="{Binding Users}" DataContext="{StaticResource viewModelKey}"  Width="750" Background="AliceBlue">

Got a hint from this post Stackoverflow

Basically I need to use Datacontext with Listbox control (even after setting the Datacontext at UserControl level). The only line that required change is:

<ListBox x:Name="lstBox" ItemsSource="{Binding Users}" DataContext="{StaticResource viewModelKey}"  Width="750" Background="AliceBlue">
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文