1

因此,当我选择电子邮件的主题时,我有一个显示电子邮件主题的列表框(我使用 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();
    }
}

提前致谢

4

3 回答 3

2

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

在您设置好ListView外观之后,您需要它看起来(ListView.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事件,然后执行以下操作:

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

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

于 2010-09-10T22:14:56.207 回答
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。OC 可以很好地处理绑定,因为集合会在添加或删除元素时通知绑定。

接下来是窗户。请注意,我没有在<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 的Message属性,因为 SelectedValue 将是当前选定的电子邮件。

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

于 2010-09-13T10:57:59.817 回答
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;
        }
    }

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

于 2010-09-08T21:36:14.940 回答