【问题标题】:WPF Observablecollection with INotifyPropertyChanged for ListView doesn't workWPF Observablecollection 与 ListView 的 INotifyPropertyChanged 不起作用
【发布时间】:2013-03-04 10:12:52
【问题描述】:

我有一个 wpf 应用程序,当我使用 Observablecollect 通过 UI 添加新值时,我想更新我的列表视图。但我没有得到我所期望的。当我添加新值时,我不会更新我的列表视图。

这是我的 CS 文件。

 using System.Collections.ObjectModel;
 using System.ComponentModel;
 using System.Data.SqlClient;
 using System.Windows;

 namespace ObservableCollectionTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public ObservableCollection<TestUser> NameList { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        NameList = GetNamesFromDBAsStringList();
        ListViewNames.ItemsSource = NameList;
        this.DataContext = this;
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        TestUser user = new TestUser();
        user.UserName = txtName.Text;
        NameList.Add(user);

        //InsertUserName(txtName.Text);
        //NameList = GetNamesFromDBAsStringList();

        txtName.Clear();
        MessageBox.Show("User added");
    }

    private ObservableCollection<TestUser> GetNamesFromDBAsStringList()
    {
        ObservableCollection<TestUser> userList = new ObservableCollection<TestUser>();

        SqlConnection connection = new SqlConnection("Data Source=Chakrapani\\SQLEXPRESS;Initial Catalog=Test;Integrated Security=True");
        connection.Open();
        string sql = "select UserID,UserName from TestUser";
        SqlCommand command = new SqlCommand(sql, connection);
        SqlDataReader reader = command.ExecuteReader();
        while (reader.Read())
        {
            TestUser testUser = new TestUser();
            testUser.UserID = (int)reader[0];
            testUser.UserName = reader[1].ToString();
            userList.Add(testUser);
        }
        reader.Close();
        connection.Close();

        return userList;
    }

    private void InsertUserName(string userName)
    {
        SqlConnection connection = new SqlConnection("Data Source=CHAKRAPANI\\SQLEXPRESS;Initial Catalog=Test;Integrated Security=True");
        connection.Open();
        string sql = string.Format("insert into TestUser values ('{0}')", userName);
        SqlCommand command = new SqlCommand(sql, connection);
        command.ExecuteNonQuery();

        connection.Close();
    }
}

public class TestUser : INotifyPropertyChanged
{
    private int _userId;
    private string _userName;

    public int UserID
    {
        get { return _userId; }
        set
        {
            _userId = value;
            NotifyPropertyChanged("UserID");
        }
    }
    public string UserName
    {
        get { return _userName; }
        set
        {
            _userName = value;
            NotifyPropertyChanged("UserName");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}
}

这是我的 xaml 文件

<Window x:Class="ObservableCollectionTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="396">
<Grid>
    <Button Content="Add User" HorizontalAlignment="Left" Margin="300,10,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1" Name="BtnAdd"/>
    <TextBox HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="264" Name="txtName"/>
    <ListView HorizontalAlignment="Left" Height="259" Margin="10,51,0,0" VerticalAlignment="Top" Width="264" Name="ListViewNames" ItemsSource="{Binding MyUserNameList}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="User ID" DisplayMemberBinding="{Binding UserID}"/>
                <GridViewColumn Header="User Name" DisplayMemberBinding="{Binding UserName}"/>
            </GridView>
        </ListView.View>
    </ListView>

</Grid>

请给我一个处理问题的线索。

【问题讨论】:

    标签: wpf data-binding observablecollection inotifypropertychanged


    【解决方案1】:

    您忘记在构造函数中添加 DataContext :

    this.DataContext = this;
    

    【讨论】:

    • 谢谢,我按照你的建议做了。但我无法将添加的数据发送到数据库。
    【解决方案2】:

    你应该将它插入到 observable 集合中而不是重新构建它

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        TestUser user = new TestUser();
        user.UserName = txtName.Text;
        InsertUserName(txtName.Text);
        NameList.Add(new TestUser {UserName = txtName.Text, UserID = ???}); //TODO: assign correct ID
        txtName.Clear();
        MessageBox.Show("User added");
    }
    

    【讨论】:

    • 我按照您的建议做了并更新了我的问题。现在我的列表视图得到更新。但附加值不会进入数据库。如何将我新添加的数据发送到数据库?
    • 你应该存储到数据库中,在添加到列表之前,可观察的集合不会保存任何东西到数据库
    • 非常感谢 ArsenMkrt。这就是我想知道的。
    • 我还有一个问题,那么INotifyPropertyChanged接口的用途是什么。没有它,我的目的现在也有效。
    • 是的,ObervableCollection 实现了 INotifyCollectionChanged 接口,足以更新添加/删除项目。另一方面,如果您像这样更新 UserName:NameList[0].UserName = "new user name";仅当您具有 INotifyPropertyChanged 时,这才会更新视图
    猜你喜欢
    • 2011-12-17
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    • 2017-01-28
    • 2013-03-30
    相关资源
    最近更新 更多