ListBox IMAP/POP3からテキストボックスに電子メールボディを表示する
質問
だから、電子メールの件名を表示するリストボックスを持っています(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();
}
}
前もって感謝します
解決
電子メールインデックスが同じままであると仮定すると(それを確認するための最も安全な方法は、フォームでフェッチされたバンドルをキャッシュすることであると思います)、私はの使用に変更します 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;
}
または、電子メールからテキストを出したいと思っている場合は、インデックスの代わりにテキストをタグに挿入できます。
他のヒント
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;
}
}
このコードはテストされていません。
あなたの問題は電子メールではなく、あなたがあなたのフォームにアイテムを表示する方法にあります。あなたはWinformsの方法で物事をやろうとしていますが、これはWinforms(一種の)には問題ありませんが、WPFでは本当に無意味でコードが多いです。 MVVMについて読んでいる必要があります(このテーマに関する質問がたくさんあります)。
WPFのバインディングインフラストラクチャを利用するコードの数行しか使用しないことを示すデモです。新しいWPFアプリを作成して、数行をコピーパストすることができます(作成したアプリに一致するように名前空間とクラス名を変更してください!)。
1つのウィンドウがあります。ここでメールをシミュレートしています。あなたはあなたの電子メールを受け取り、それらをコレクションに捨てるでしょう:
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; }
}
型フェイクメールの観測値をウィンドウに追加しました。 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>
いくつかの細かいメモ:リストボックスのもの itemsource ウィンドウで定義した観測可能な収集にバインドされています。 ListBoxは、そのコレクションに出入りするアイテムをリッスンし、DataTemplateを使用してCollecitonの各アイテムのUIを表示します。
ItemTemplateが検索するFAKEMAILごとに、の新しいインスタンスが作成されます dataTemplate そして内容、そして設定します datacontext フェイクメールインスタンスへのテンプレートの。つまり、dataTemplate内では、FakeMailインスタンスのプロパティに単純にバインドでき、実行時にすべてが配線されます。
リストボックスには、呼ばれるプロパティがあります SelectedValue, 、電子メールメッセージを表示するために使用できます。リストボックスでアイテムを選択するとき、 SelectedValue dataTemplateのデータコンテキストであるitemsourceのインスタンスです。 UIのそのアイテムに現在表示されているもの。したがって、現在選択されている電子メールのメッセージを表示するには、ItemsourceのselectedValueのものにバインドする必要があります メッセージ selectedValueが現在選択されている電子メールになるため、プロパティ。
以上です。聞いていない、「 r n」bs。カップルがバインドされ、観察可能なコレクション。