Показать тело письма в текстовом поле из списка Imap / pop3 - PullRequest
1 голос
/ 11 сентября 2010

Итак, у меня есть список, который показывает тему письма (я использую клиент chilkat imap), когда я выбираю тему письма, я хочу показать тело сообщения в текстовом поле, но я не могу понять, как это сделать Я, конечно же, использую событие listin 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 ]

2 голосов
/ 11 сентября 2010

Предполагая, что индексы электронной почты остаются прежними (я думаю, что самый безопасный способ убедиться в этом - кэшировать извлеченный пакет в форме), я бы переключился на использование ListView вместо ListBoxи затем я добавляю индексы в список в виде отдельного столбца или в 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;
}

Или, если вы уверены, что когда-либо захотите получить текст из электронных писем, вы можете вставить текст в теги вместо индексов.

1 голос
/ 13 сентября 2010

Ваша проблема не в электронном письме, а в том, как вы отображаете элементы в форме.Вы пытаетесь делать что-то в 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; }
}

Я добавил ObservableCollection типа FakeEmail в окно.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 для отображения пользовательского интерфейса для каждого элемента в коллекции.

Для каждого FakeEmail, который находит ItemTemplate, он создает новый экземпляр DataTemplate и его содержимое и устанавливает DataContext шаблона в экземпляр FakeEmail.Это означает, что в DataTemplate я могу просто привязаться к свойствам экземпляра FakeEmail, и все будет подключено во время выполнения.

ListBox имеет свойство с именем SelectedValue , которое я могу использовать дляпоказать сообщение электронной почты.Когда вы выбираете элемент в ListBox, SelectedValue является экземпляром ItemsSource, который является DataContext объекта DataTemplate;то, что в данный момент отображается в этом элементе в пользовательском интерфейсе.Итак, чтобы показать текущее выбранное сообщение электронной почты, мне просто нужно привязать свойство Message элемента ItemSource SelectedValue, поскольку SelectedValue будет выбранным в настоящий момент письмом.

И это все.Нет прослушивания, нет "\ r \ n" BS.Пара связывает и наблюдаемая коллекция.

1 голос
/ 09 сентября 2010

В вашем 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;
        }
    }

Обратите внимание, что этот код не проверен.

...