【问题标题】:ListBox does not update entries automaticly when using binding使用绑定时 ListBox 不会自动更新条目
【发布时间】:2014-07-23 22:32:29
【问题描述】:

向列表框添加新数据时,我在更新列表框时遇到了一些问题。这是我的代码

我的列表框有

 <ListBox Name="EmailList" ItemsSource="{Binding ListBoxData, Mode=TwoWay}"

这是我的程序:

public partial class MainWindow : Window
{

    string hostname = Properties.Settings.Default.pop_host;
    int port = Properties.Settings.Default.pop_port;
    bool useSsl = Properties.Settings.Default.pop_usessl;
    string username = "recent:" + Properties.Settings.Default.username;
    string password = Properties.Settings.Default.password;

        // When this button is pressed the program starts a backgroundworker
        // that begins the download of mails
    private void MenuItem_Click(object sender, RoutedEventArgs e)
    {
        BackgroundWorker getNewMail = new BackgroundWorker();
        getNewMail.DoWork += newEmail;
        getNewMail.RunWorkerAsync();
        getNewMail.RunWorkerCompleted += updateList;
    }

    // The actual function that downloads the mails (Using OpenPOP)
    private void newEmail(object sender, DoWorkEventArgs e)
    {
    List<Message> allEmail = FetchAllMessages(hostname, port, useSsl, username, password);
            ListBoxData = new List<EmailEntry> { };

        foreach (Message singleEmail in allEmail)
        {
                var mailData = new ListBoxDataClass { theMessage = singleEmail, truncate = 40 };
                readyUpListBoxData(mailData);
                ListBoxData.Add(new EmailEntry { from = mailData.displayName, subject = mailData.partOfBody, messageID = singleEmail.Headers.MessageId.ToString() });   
        }
    }

    public class ListBoxDataClass
    {
        public Message theMessage { get; set; }
        public int truncate { get; set; }

        public string partOfBody { get; set; }
        public string displayName { get; set; }
    }

    // A function that does different things with the downloaded data
    public void readyUpListBoxData(ListBoxDataClass data)
    {
        MessagePart theEmailTxt = data.theMessage.FindFirstPlainTextVersion();
        string noLineBreaks = theEmailTxt.GetBodyAsText().ToString().Replace(System.Environment.NewLine, " ");
        data.partOfBody = noLineBreaks.Length <= data.truncate ? noLineBreaks : noLineBreaks.Substring(0, data.truncate) + " ..";
        data.displayName = data.theMessage.Headers.From.DisplayName.ToString();
        if (data.displayName == "")
        {
            data.displayName = data.theMessage.Headers.From.Address.ToString();
        }
        data.displayName += " <" + data.theMessage.Headers.From.Address.ToString() + ">";
    }
}

我相信我应该使用所谓的可观察集合或类似的东西?我只是看不到如何在我的程序中使用它。我希望你们中的一些人可以帮助我使用 Observable 集合或指出我可以使用的其他东西,这正是我需要的。

我正在考虑使用诸如计时器之类的东西来实现它,但我不确定这是否是一个好习惯?

【问题讨论】:

  • 您将创建一个公共 observablecollection ListBoxData 以便 xaml 可以访问它
  • 尽管@Tsukasa 的推理很糟糕(xaml 可以访问它),但 正确答案。请查看 MSDN 上的ObservableCollection<T> Class 页面了解更多信息。
  • @Sheridan SO 应该给你警长批 :)
  • dude ...... 是 i>一个警长徽章,但它是一个金色的徽章,并且有一个人担任选举主持人至少1年 i> .反正我对这样的事情不感兴趣……我只是“看到就说”,所以如果有人添加了质量差的问题或答案,你最好相信我会告诉他们。 :)

标签: c# wpf data-binding listbox


【解决方案1】:

为您的 ListBoxData 创建公共属性,如下所示:

     public partial class MainWindow : Window
     {

         public ObservableCollection<EmailEntry > ListBoxData{get;set;}

         public MainWindow()
         {
             ListBoxData = new ObservableCollection<EmailEntry >();
             InitializeComponents();
         }

        private void newEmail(object sender, DoWorkEventArgs e)
        {
             List<Message> allEmail = FetchAllMessages(hostname, port, useSsl, username, password);


            foreach (Message singleEmail in allEmail)
            {
                var mailData = new ListBoxDataClass { theMessage = singleEmail, truncate = 40 };
                readyUpListBoxData(mailData);
                ListBoxData.Add(new EmailEntry { from = mailData.displayName, subject = mailData.partOfBody, messageID = singleEmail.Headers.MessageId.ToString() });   
            }
      }

【讨论】:

    【解决方案2】:

    您可以实现INotifyPropertyChanged,然后在完成添加后提升ListBoxData 属性,或者只需将ListBoxData 更改为ObservableCollection,因为它默认实现INPC

    【讨论】:

    • -1 这与INotifyPropertyChanged 接口无关...我相信您指的是INotifyCollectionChanged 接口。我们谈论的是添加项目,而不是更改属性值。
    • @Sheridan 你是什么意思它与INPC 无关。您可以在 ListBox 上的每个添加上引发属性更改,以使用绑定或像我说的那样更新它。将其更改为ObservableCollection。另外,ObservableCollection 在下面实现了 INPCINCC,所以让你的 cmets 直截了当,我希望你知道你在说什么。
    • 把你的cmets弄直...哇,冷静点...你为什么认为我写了我相信你指的是INotifyCollectionChanged代替界面?因为ObservableCollection&lt;T&gt; 当然实现了它......没有其他理由提及它。所以我的cmets 直的。 您可以在 ListBox 上的每个添加项上提高属性更改...真的吗?这样做时您会使用什么属性名称?当INotifyCollectionChanged 接口为我们这样做时,为什么还要费心去做呢?这就是它的用途......
    • .. 所以,正如我所说,NotifyPropertyChanged 接口在这方面没有任何作用,并且与这个问题无关。归根结底,你犯了一个小错误,我们有时都会犯。你本可以更正它,我会删除反对票......但出于某种原因,你想要一个毫无意义的论点。这样做有什么意义?
    • @Sheridan 是的,它确实发挥了作用。在场景下,ObservableCollection 通过INCC 调用INPC,从而更新UI。在 Window 上实现 INPC 并在当前实现上调用 OnPropertyChange 将在他添加项目的 foreach 循环之后更新条目。我的回答都是正确的,但他当然应该使用ObservableCollection
    猜你喜欢
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多