nukleos
nukleos

Reputation: 419

Binding ObservableCollection of objects trouble

I'm trying to code an rssreader and would be pleased for some architecture hints. My reader main window hosts two wpf pages which are loaded into frames, it's a "bottombar" where user can select different rss providers. In the main frame (or page) is my listview. Because of an loading animation and UI Freeze I've an extra class with a backgroundworker which fills an observable collection with RSS Data, when I'm debugging, it fills my collection correctly. In main page i'm setting the datacontext to this observable collection but listview doesn't show anything, here I'm stuck.

That's what I have:

MainPage XAML:

> <ListBox ItemsSource="{Binding}" DisplayMemberPath="RssTitle"
> IsSynchronizedWithCurrentItem="True"
> SelectionChanged="itemsList_SelectionChanged"
> ItemContainerStyle="{DynamicResource listboxitem_style}" Height="396"
> HorizontalAlignment="Left" Margin="126,12,0,0" Name="ListBox1"
> VerticalAlignment="Top" Width="710"></ListBox>

ListBox1.DataContext = GetRssItems.observable_list;

Bottompage to get another rss feed:

GetRssItems getitems = new GetRssItems();
GetRssItems.observable_collection = null;
getitems.start_bg_worker("url");

GetRssItems.cs

public class GetRssItems
    {
        public static ObservableCollection<RSSItem> observable_collection { get; set; }
        public static string tmp_url;
        public BackgroundWorker worker = new BackgroundWorker();


        public void start_bg_worker(string url)
        {


            if (!worker.IsBusy)
            {

                worker.DoWork += new DoWorkEventHandler(worker_DoWork);
                worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
                worker.RunWorkerAsync(url);
            }
        }
}

In BackgroundWorkers DoWork I'm receiving rss items with linq and add it to my observable collection:

  observable_collection.Add(new RSSItem(item.tmp_Title, item.tmp_Link, item.tmp_Description, item.tmp_pubDate, item.tmp_ImageUrl));

Seperate class RSSItem.cs

public class RSSItem
    {
         public string RssTitle { get; set; }
            public string RssLink { get; set; }
            public string RssDescription { get; set; }
            public string RsspubDate { get; set; }
            public string RssImageUrl { get; set; }

            public RSSItem(string rsstitle, string rsslink, string rssdescription, string rsspubdate, string rssimageurl)
            {
                RssTitle = rsstitle;
                RssLink = rsslink;
                RssDescription = rssdescription;
                RsspubDate = rsspubdate;
                RssImageUrl = rssimageurl;
            }
    }

Thanks for your time and hints. Best Regards

Upvotes: 0

Views: 1934

Answers (2)

Steve Py
Steve Py

Reputation: 34773

You need to read up a bit MVVM to get the most benefit from WPF. Your line setting the listbox's datacontext is rather confusing.

What you should have is your main window's (xaml) data context set to a view model class that contains your observable collection. The list box's ItemsSource is set to that property name.

For example:

public class MainViewModel : INotifyPropertyChanged
{
   public ObservableCollection<RSSItem> RSSItems
   {
      get;
      set;
   }
   // Other stuff applicable to the main window.
}

When the view is constructed, pass an instance of the MainViewModel to it's DataContext. Then the Xaml for the ListBox would be:

<ListBox ItemsSource={Binding Path=RSSItems} ... />

If you want to be able to set/change the RSSItems collection instance (I.e. public setter) then you should set it up it's setter with the NotifyPropertyChanged event, however if you just add/remove items then this shouldn't be necessary. (I.e. loading populating the items in the constructor.)

Upvotes: 2

Nahum
Nahum

Reputation: 7197

use the following: the data context should be the Object getitems

<ListBox  ItemsSource="{Binding observable_collection}"  Height="167" Margin="0" Name="listBox1" Width="330" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Top">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding RssTitle}"  FontWeight="Bold" FontSize="16" />
                                <TextBlock Text="{Binding RssLink}"  FontSize="16"/>
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>

PS: your naming is HORRBILE

Upvotes: 1

Related Questions