将可观察集合绑定到listview wpf

时间:2014-06-25 14:54:25

标签: c# wpf

我正在为工作制作电子邮件客户端,但我无法以正确的方式将可观察集合绑定到我的列表视图。请指教,因为我无法在线找到我的确切问题

C#

public partial class Mail : UserControl
{
    ObservableCollection<GetMails> BindMe = new ObservableCollection<GetMails>();
    public Mail()
    {
        InitializeComponent();
    }

    private void Grid_Loaded_1(object sender, RoutedEventArgs e)
    {
        BindMe = FetchAllHeaders(server, port, false, username, password);
        lstMail.ItemsSource = BindMe.ToList();
    }

    private ObservableCollection<GetMails> FetchAllHeaders(string hostname, int port, bool useSsl, string username, string password)
    {
        // The client disconnects from the server when being disposed
        using (Pop3Client client = new Pop3Client())
        {
            GetMails gm = new GetMails();

            // Connect to the server
            client.Connect(hostname, port, useSsl);

            // Authenticate ourselves towards the server
            client.Authenticate(username, password);

            // Get the number of messages in the inbox
            int messageCount = client.GetMessageCount();

            // We want to download all messages
            ObservableCollection<GetMails> getHeaders = new ObservableCollection<GetMails>();

            // Messages are numbered in the interval: [1, messageCount]
            // Ergo: message numbers are 1-based.
            // Most servers give the latest message the highest number
            for (int i = messageCount; i > 0; i--)
            {
                MessageHeader headers = client.GetMessageHeaders(i);
                RfcMailAddress from = headers.From;
                Message message = client.GetMessage(i);
                gm.Header = client.GetMessageHeaders(i).Subject;
                gm.From = from.MailAddress.ToString();
                int count = 0;
                foreach (MessagePart attachment in message.FindAllAttachments())
                {
                    count++; 
                }
                gm.NumberAttach = count;
                getHeaders.Add(gm);
            }


            // Now return the fetched messages
            return getHeaders;
        }
    }
}

XAML

<UserControl x:Class="VeriMail.Mail"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid Loaded="Grid_Loaded_1" Margin="0,0,-132,0">
    <ListView x:Name="lstMail" Height="399" VerticalAlignment="Top" Margin="0,0,-67,-99" ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.CanContentScroll="True">
        <ListView.View>
            <GridView>
                <GridViewColumn Width="140" Header="Subject" />
                <GridViewColumn Width="140" Header="From" />
                <GridViewColumn Width="140" Header="Number of Attachments"/>
            </GridView>
        </ListView.View>
    </ListView>

</Grid>

我这样做时得到的输出只是VeriMail.GetMail

如果我将gridview更改为:

<GridViewColumn Width="140" Header="Subject" DisplayMemberBinding="{Binding Header}"/>
<GridViewColumn Width="140" Header="From" DisplayMemberBinding="{Binding From}"/>
<GridViewColumn Width="140" Header="Number of Attachments" DisplayMemberBinding="{Binding NumberAttach}"/>

然后输出更改为我想要的信息,但它会复制一个电子邮件,最后一个插入到可观察集合中。

3 个答案:

答案 0 :(得分:1)

更新:问题是当您致电ToList时,系统会被复制,并且未来会反映出更改。删除该方法调用,它应该工作。

然而,在XAML中绑定ItemsSource比在后面的代码中绑定更好:

<ListView x:Name="lstMail" ItemsSource="{Binding BindMe, RelativeSource={RelativeSource AncestorType=UserControl}}" Height="399" VerticalAlignment="Top" Margin="0,0,-67,-99" ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.CanContentScroll="True">
    <ListView.View>
        <GridView>
            <GridViewColumn Width="140" Header="Subject" />
            <GridViewColumn Width="140" Header="From" />
            <GridViewColumn Width="140" Header="Number of Attachments"/>
        </GridView>
    </ListView.View>
</ListView>

并且也不会在BindMe中更改FetchAllHeaders()集合引用本身,而是修改它的内容。否则绑定不会起作用,因为引用再次被更改。

答案 1 :(得分:1)

如另一个答案所述,它是在XAML中绑定的通常做法(例如使用MVVM模式)。如果你这样做了,你可能已经找到了这个错误......

lstMail.ItemsSource = BindMe.ToList();

当您致电ToList()时,您会创建一个包含可观察集合内容的全新List<GetMails>。当您添加新项目时,列表不会更改 - 它是副本,并且对原始集合一无所知。

尝试

lstMail.ItemsSource = BindMe;

这应该可以解决你的问题。

答案 2 :(得分:0)

lstMail.ItemsSource = BindMe.ToList();

应该是

lstMail.ItemsSource = BindMe;

绑定到列表与绑定到ObservableCollection不同。 Observable collection是用于绑定的对象,因为它实现了ICollectionChanged。列表没有。