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

发布于 2024-09-18 20:14:13 字数 1376 浏览 13 评论 0 原文

因此,我有一个显示电子邮件主题的列表框(我使用 chilkat imap 客户端),当我选择电子邮件主题时,我想在文本框中显示邮件正文,但我不知道该怎么做,显然我使用列表框 selectindexchanged 事件,但我将如何处理它

到目前为止代码

// 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();
    }
}

提前感谢

So I have a listbox that shows the subject of an email (I use the chilkat imap client) when I select the subject of an email I want to show the message body in a textbox but i cant figure out how to do it, obviusly i use the listbox selectindexchanaged event but how would i go about it

Code So Far

// 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();
    }
}

thanks in advance

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

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

发布评论

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

评论(3

瑶笙 2024-09-25 20:14:13

假设电子邮件索引保持不变(我认为确保这一点的最安全方法是将获取的捆绑包缓存在表单中),我将更改为使用 ListView 而不是 < code>ListBox,然后我将索引添加到列表中,无论是作为单独的列还是在项目的 Tag 中。

ListView 设置为您需要的外观后(ListView.View = View.Details;ListView.MultiSelect = false;< /code> 可能是主要的)而不是:

listBox1.Items.Add(email.From + ": " + email.Subject);

你可以做类似的事情(如果你用 Tag 方式来做,这稍微容易一些,但有些人认为不好):

listView1.Items.Add(email.From + ": " + email.Subject).Tag = i;

然后当用户选择列表中的主题,正如您所说,您处理 ListView.SelectedIndexChanged 事件,然后执行类似以下操作:

if(ListView.SelectedItems.Count > 0)
{
    textBox1.Text = bundle.GetEmail((int)ListView.SelectedItems[0].Tag).Body;
}

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

Assuming that the email indexes stay the same (I think the safest way to make sure of that would be to cache the fetched bundle in the form), I'd change to using a ListView instead of the ListBox and then I'd add the indexes to the list, either as a separate column or in the Tag of the items.

After you'd set up the ListView to look as you need it to look (ListView.View = View.Details; and ListView.MultiSelect = false; are probably the main ones) instead of:

listBox1.Items.Add(email.From + ": " + email.Subject);

you could do something like (if you do it the Tag way, which is slightly easier but some people think is bad):

listView1.Items.Add(email.From + ": " + email.Subject).Tag = i;

And then when the user selects a subject in the list, as you say, you handle the ListView.SelectedIndexChanged event and then just do something like:

if(ListView.SelectedItems.Count > 0)
{
    textBox1.Text = bundle.GetEmail((int)ListView.SelectedItems[0].Tag).Body;
}

Or if you're sure you only ever want to get out the text from the emails, you could insert the texts into the tags instead of the indexes.

烟酉 2024-09-25 20:14:13

在您的 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;
        }
    }

请注意此代码未经测试。

In your xaml set up the listboxes to bind to the properties you'd like, and set up event handlers for when the selection changes.

    <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>

Then in your code behind. bind the listboxes to a list of the email objects.

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

finally you need to handle the event from the listboxes.

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

Please note this code is not tested.

晚雾 2024-09-25 20:14:13

您的问题不在于电子邮件,而在于您如何在表单中显示项目。您正在尝试以 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 添加到窗口中。 OC 与绑定配合得很好,因为当添加或删除元素时集合会通知绑定。

接下来,窗户。请注意,我在这里没有显示 定义,但我已将窗口命名为 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 的 Message 属性,因为 SelectedValue 将是当前选定的电子邮件。

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

Your issue is not with the email but with how you are displaying items in your form. You are trying to do things in a winforms way, which is fine for winforms (kind of) but really is pointless and code-heavy in WPF. You should do some reading about MVVM (plenty of questions here on the subject).

Here's a demo showing what you want to do using only a few lines of code that takes advantage of the binding infrastructure of WPF. You can create a new WPF app and copypaste the few lines (change my namespace and class names to match the app you create!) and see it in action.

There is one window. I'm simulating emails here; you'd get your emails and dump them in the collection:

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; }
}

I've added an ObservableCollection of type FakeEmail to the window. OCs work well with binds, as the collection notifies binds when elements are added or removed.

Next, the window. Please note, I'm not showing the <Window definition here, but I have named the 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>

Some of the finer notes: The ListBox's ItemsSource is bound to the ObservableCollection I defined on the window. The ListBox will listen for items coming and going in that collection, and use the DataTemplate to display UI for each item in the colleciton.

For each FakeEmail the ItemTemplate finds, it creates a new instance of the DataTemplate and contents, and sets the DataContext of the template to the FakeEmail instance. That means, within the DataTemplate I can simply bind against the properties of a FakeEmail instance and everything gets wired up at runtime.

The ListBox has a property called SelectedValue, which I can use to show the email message. When you select an item in the ListBox, SelectedValue is the instance from ItemsSource that is the DataContext of the DataTemplate; that which is currently displayed in that item in the UI. So, in order to show the currently selected email's message, I just need to bind against the ItemSource's SelectedValue's Message property, since SelectedValue will be the currently selected email.

And that's it. No listening, no "\r\n" BS. A couple binds and an Observable collection.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文