在列表框Imap / pop3中的文本框中显示电子邮件正文

时间:2010-09-10 21:43:04

标签: c# winforms email imap chilkat

所以我有一个列表框,显示电子邮件的主题(我使用chilkat imap客户端)当我选择电子邮件的主题我想在文本框中显示邮件正文但我无法弄清楚如何做到这一点,显然我使用listbox selectindexchanaged事件,但我将如何去做呢

代码到目前为止

// Create an object, connect to the IMAP server, login,
        // and select a mailbox.
        Chilkat.Imap imap = new Chilkat.Imap();
        imap.UnlockComponent("UnlockCode");
        imap.Connect("Imap URL");
        imap.Login("email address", "password");
        imap.SelectMailbox("Inbox");

        // Get a message set containing all the message IDs
        // in the selected mailbox.
        Chilkat.MessageSet msgSet;
        msgSet = imap.Search("ALL", true);

        // Fetch all the mail into a bundle object.
        Chilkat.EmailBundle bundle = new Chilkat.EmailBundle();
        bundle = imap.FetchBundle(msgSet);

        // Loop over the bundle and display the From and Subject.
        Chilkat.Email email;
        int i;
        for (i = 0; i < bundle.MessageCount - 1; i++)
        {

            email = bundle.GetEmail(i);
            listBox1.Items.Add(email.From + ": " + email.Subject);
            textBox1.Text = email.Body ;

        }

        // Save the email to an XML file
        bundle.SaveXml("bundle.xml");



        // Disconnect from the IMAP server.
        // This example leaves the email on the IMAP server.
        imap.Disconnect();
    }
}

提前致谢

3 个答案:

答案 0 :(得分:2)

假设电子邮件索引保持不变(我认为最安全的方法是确保在表单中缓存已获取的包),我将更改为使用ListView而不是{ {1}}然后我将索引添加到列表中,作为单独的列或在项目的ListBox中。

在设置Tag后,您需要查看(ListViewListView.View = View.Details;可能是主要的),而不是:

ListView.MultiSelect = false;

你可以做类似的事情(如果你以listBox1.Items.Add(email.From + ": " + email.Subject); 的方式做到这一点,这有点容易,但有些人认为不好):

Tag

然后,当用户选择列表中的主题时,如您所说,您处理listView1.Items.Add(email.From + ": " + email.Subject).Tag = i; 事件,然后执行以下操作:

ListView.SelectedIndexChanged

或者,如果您确定只想从电子邮件中删除文本,则可以将文本插入标记而不是索引。

答案 1 :(得分:1)

在您的xaml中设置列表框以绑定到您想要的属性,并为选择更改时设置事件处理程序。

    <StackPanel>
        <ListBox Name="listbox1" SelectionChanged="listbox_SelectionChanged">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=From}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <ListBox Name="listbox2" SelectionChanged="listbox_SelectionChanged">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=Subject}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <TextBox Name="textbox1"></TextBox>
    </StackPanel>

然后在你的代码后面。将列表框绑定到电子邮件对象列表。

        listbox1.ItemsSource = emails;
        listbox2.ItemsSource = emails;

最后你需要处理列表框中的事件。

    private void listbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ListBox listbox = (ListBox)sender;
        foreach (Email email in listbox.SelectedItems)
        {
            textbox1.Text = email.Body;
        }
    }

请注意,此代码未经过测试。

答案 2 :(得分:1)

您的问题不在于电子邮件,而在于您在表单中显示项目的方式。你正试图以winforms的方式做事,这对winforms来说很好(有点)但在WPF中真的没有意义且代码很重。你应该阅读一些关于MVVM的内容(这里有很多关于这个主题的问题)。

这是一个演示,展示了您只想使用几行代码来利用WPF的绑定基础结构。您可以创建一个新的WPF应用程序并复制几行(更改我的命名空间和类名称以匹配您创建的应用程序!)并查看它的实际效果。

有一个窗口。我在这里模拟电子邮件;你会收到你的电子邮件并将它们转储到收藏中:

public partial class MainWindow : Window
{
    public ObservableCollection<FakeEmail> Emails { get; private set; }

    public MainWindow()
    {
        Emails = new ObservableCollection<FakeEmail>();
        // simulates emails being received; you would popoulate with valid emails IRL
        Emails.Add(new FakeEmail 
            { From = "herp", Subject = "derp", Message = "herp derp" });
        Emails.Add(new FakeEmail 
            { From = "foo", Subject = "bar", Message = "foo bar" });
        Emails.Add(new FakeEmail 
            { From = "Binding", Subject = "Rocks", Message = "Binding rocks" });
        InitializeComponent();
    }
}
/// <summary>
/// I don't have your libraries
/// </summary>
public sealed class FakeEmail
{
    public string From { get; set; }
    public string Subject { get; set; }
    public string Message { get; set; }
}

我在窗口中添加了一个FakeEmail类型的ObservableCollection。 OCs可以很好地处理绑定,因为当添加或删除元素时,集合会通知绑定。

接下来,窗口。请注意,我没有在此处显示<Window定义,但我将窗口命名为emailClient

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <ListBox
        x:Name="emailList"
        ItemsSource="{Binding Emails, ElementName=emailClient}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock
                        Text="{Binding From}" />
                    <TextBlock
                        Text="{Binding Subject}"
                        TextWrapping="NoWrap"
                        TextTrimming="CharacterEllipsis" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <TextBlock
        Grid.Column="1"
        Text="{Binding SelectedValue.Message, ElementName=emailList, FallbackValue='Select an email pls'}" />
</Grid>

一些更好的注释:ListBox的 ItemsSource 绑定到我在窗口上定义的ObservableCollection。 ListBox将侦听该集合中来来往往的项目,并使用DataTemplate显示集合中每个项目的UI。

对于ItemTemplate找到的每个FakeEmail,它会创建 DataTemplate 和内容的新实例,并将模板的 DataContext 设置为FakeEmail实例。这意味着,在DataTemplate中,我可以简单地绑定FakeEmail实例的属性,并且所有内容都会在运行时连接起来。

ListBox有一个名为 SelectedValue 的属性,我可以用它来显示电子邮件。当您在ListBox中选择一个项目时, SelectedValue 是ItemsSource中的实例,它是DataTemplate的DataContext;当前显示在UI中该项目中的内容。因此,为了显示当前选择的电子邮件消息,我只需要绑定ItemSource的SelectedValue的消息属性,因为SelectedValue将是当前选择的电子邮件。

就是这样。没有听,没有“\ r \ n”BS。一对夫妇和一个Observable集合。