/Samples/Controls/Marquee/Silverlight/Marquee-Silverlight/NewsViewModel.cs
C# | 166 lines | 131 code | 20 blank | 15 comment | 4 complexity | f8254ec9a88578e363a9e2eb3e0f8cfe MD5 | raw file
- using System;
- using System.Collections.ObjectModel;
- using System.ComponentModel;
- using System.Reactive.Concurrency;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Reactive.Linq;
- using System.Text;
- using System.Windows;
- using System.Windows.Input;
- using System.Xml.Linq;
-
- namespace Marquee_Silverlight
- {
- public class NewsViewModel : INotifyPropertyChanged
- {
- private IDisposable _observation;
- private Headline _expandedHeadline;
-
- public NewsViewModel()
- {
- Headlines = new ObservableCollection<Headline>();
-
- // The Silverlight permissions model places restrictions on which sites we can access if we are hosted in the browser.
- string feedUrl = null;
- if (Application.Current.IsRunningOutOfBrowser)
- {
- feedUrl = "http://feeds.bbci.co.uk/news/rss.xml";
- }
-
- if (!string.IsNullOrEmpty(feedUrl))
- {
- var webRequest = WebRequest.Create(feedUrl);
-
- _observation = Observable.FromAsyncPattern<WebResponse>(webRequest.BeginGetResponse,
- webRequest.EndGetResponse)()
- // Execute the web request to get XML
- .Select(response => response.GetResponseStream())
- .Select(stream =>
- {
- using (var reader = new StreamReader(stream, Encoding.UTF8))
- return reader.ReadToEnd();
- })
- .Select(xml => XDocument.Parse(xml)) // Parse the XML
- .SelectMany(document => document.Descendants("channel").Descendants("item").ToObservable())
- // Extract the item elements
- .Select(xelem => new Headline(this) // Convert from XML into our model class
- {
- Title = xelem.Descendants("title").First().Value,
- Summary = xelem.Descendants("description").First().Value,
- })
- .ObserveOn(Scheduler.CurrentThread)
- .Subscribe(headline => Headlines.Add(headline), // And add the object into the bound collection
- ex => Headlines.Add(new Headline(this) // Render exception details into the marquee
- {
- Title =
- String.IsNullOrEmpty(ex.Message)
- ? ex.GetType().FullName
- : ex.Message
- }));
- }
- else
- {
- Headlines.Add(new Headline(this)
- {
- Title = "Welcome to the MVVM-compatible Marquee control.",
- Summary = "Unfortunately Silverlight security policies stop us from downloading an interesting content right now. Try running this out-of-browser to access BBC headlines."
- });
- Headlines.Add(new Headline(this)
- {
- Title = "How to run out-of-browser?",
- Summary = "Right click on this marquee and choose 'Install onto this computer'"
- });
- Headlines.Add(new Headline(this)
- {
- Title = "This doesn't look much like a marquee control.",
- Summary = "Perhaps your browser is too big. As you resize it the marquee will decrease in size. Once the visible window is smaller than the content, it will start to scroll."
- });
- Headlines.Add(new Headline(this)
- {
- Title = "What makes it MVVM compatible?",
- Summary = "The content is driven purely by databinding onto a view-model and the scrolling action is driven by the size of the content. So there is no need for code-behind."
- });
- }
- }
-
- /// <summary>
- /// The headline which currently has its summary displayed
- /// </summary>
- public Headline ExpandedHeadline
- {
- get
- {
- return _expandedHeadline;
- }
- set
- {
- _expandedHeadline = value;
- OnPropertyChanged("ExpandedHeadline");
- }
- }
-
-
- /// <summary>
- /// List of all headlines
- /// </summary>
- public ObservableCollection<Headline> Headlines { get; private set; }
-
- public event PropertyChangedEventHandler PropertyChanged;
-
- public void OnPropertyChanged(string propertyName)
- {
- PropertyChangedEventHandler handler = PropertyChanged;
- if (handler != null)
- handler(this, new PropertyChangedEventArgs(propertyName));
- }
- }
-
- /// <summary>
- /// An implementation of ICommand. It's "temporary" in the sense that it's not a very good implementation of ICommand, it's just about enough for the purpose of this example.
- /// </summary>
- public class TemporaryDelegateCommand : ICommand
- {
- private Action _action;
-
- public TemporaryDelegateCommand(Action action)
- {
- _action = action;
- }
-
- public void Execute(object parameter)
- {
- _action();
- }
-
- public bool CanExecute(object parameter)
- {
- return true;
- }
-
- public event EventHandler CanExecuteChanged
- {
- add { }
- remove { }
- }
- }
-
- /// <summary>
- /// Holds details of a news headline
- /// </summary>
- public class Headline
- {
- public Headline(NewsViewModel owner)
- {
- SelectCommand = new TemporaryDelegateCommand(() => owner.ExpandedHeadline = this);
- }
-
- public string Title { get; set; }
- public string Summary { get; set; }
-
- public ICommand SelectCommand { get; set; }
- }
-
-
- }