Download this article as a PDF Welcome back :) This week we are going to look at something more exciting and a much required feature for any twitter client – auto refresh so as to show new status updates. We are going to achieve this using Silverlight 4 Timers and a bit and refresh our datagrid every 2 minutes to show new updates. We will do this so that we do only minimal request to the twitter api, so that twitter does not block us – there is a limit of 150 request an hour. Let us get started now. Also we will get the profile user id hyperlinked, so that when ever the user click on it, we will take them to their twitter page. Also it was a pain to always run this application by pressing F5, then it would open in a browser you would have to right click uninstall and install it again to see any changes. All this and yet we were not able to debug it :( Now there is a solution for this to run a silverlight application directly out of browser and yet have the debug feature. Super cool, here is how. Right on the Silverlight project and go to debug and then select the Out-Of-Browser application option and choose the *.Web project. Then just right click on the SL project and set as Startup Project. There you go, now every time you press F5, it will automatically run out of browser and still have the debug options. I go to know about this after some binging. Now let us jump to the core straight away. 1) To get the user id hyperlinked, we need to have a DataGridTemplateColumn and within that have a HyperLinkButton. The code for this will be <data:DataGridTemplateColumn>
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<HyperlinkButton Click="HyperlinkButton_Click" Content="{Binding UserName}" TargetName="_blank" ></HyperlinkButton>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
2) Now let us look at how we are getting this done by looking into HyperlinkButton_Click event handler. There we will dynamically set the NavigateUri to the twitter page. I tried to do this using some binding, eval like stuff as in ASP.NET, but no luck!
private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
HyperlinkButton hb = (HyperlinkButton)e.OriginalSource;
hb.NavigateUri = new Uri("http://twitter.com/" + hb.Content.ToString(), UriKind.Absolute);
}
3) Now we need to switch on our Timer right in the OnNavigated to event on our SL page. So we need to modify our OnNavigated event to some thing like below:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
image1.Source = new BitmapImage(new Uri(GlobalVariable.profileImage, UriKind.Absolute));
this.Title = GlobalVariable.getUserName() + " - Home";
if (!GlobalVariable.isLoggedin())
this.NavigationService.Navigate(new Uri("/Login", UriKind.Relative));
else
{
currentGrid = "Timeline-Grid";
TwitterCredentialsSubmit();
myDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 60, 0);
myDispatcherTimer.Tick += new EventHandler(Each_Tick);
myDispatcherTimer.Start();
}
}
I use a global string – here it is currentGrid variable to indicate what is bound in the datagrid so that after every timer tick, I can rebind the latest data to it again. Like I will only rebind the friends timeline again if the data grid currently holds it and I’ll only rebind the respective list status again in the data grid, if already a list status is bound to the data grid.
In the above timer code, its set to trigger the Each_Tick event handler every 1 minute (60 seconds). TimeSpan takes in (days, hours, minutes, seconds, milliseconds).
4) Now we need to set the list name in the currentGrid variable when a list button is clicked. So add the code line below to the list button event handler
currentGrid = currentList = b.Content.ToString();
5) Now let us see how Each_Tick event handler is implemented.
public void Each_Tick(object o, EventArgs sender)
{
if (!currentGrid.Equals("Timeline-Grid"))
getListStatuses(currentGrid);
else
{
WebRequest.RegisterPrefix("https://", System.Net.Browser.WebRequestCreator.ClientHttp);
WebClient myService = new WebClient();
myService.AllowReadStreamBuffering = true;
myService.UseDefaultCredentials = false;
myService.Credentials = new NetworkCredential(GlobalVariable.getUserName(), GlobalVariable.getPassword());
myService.DownloadStringCompleted += new DownloadStringCompletedEventHandler(TimelineRequestCompleted);
myService.DownloadStringAsync(new Uri("https://twitter.com/statuses/friends_timeline.xml"));
}
}
If the data grid hold friends timeline, I just use the same bit of code we had already to bind the friends timeline to the data grid. Copy Paste.
But if it is some list timeline that is bound in the datagrid, I then call the getListStatus method with the currentGrid string which will actually be holding the list name.
6) I wanted to make the hyperlinks inside the status message as hyperlinks and when the user clicks on it, we can then open that link. I tried using a convertor and using a regex to recognize a url and wrap it up with a href, but that is not gonna work in silverlight textblock :( Anyways that convertor code is in the zip file.
7) You can get the complete project files from here.
8) Please comment below for your doubts, suggestions, improvements. I will try to reply as early as possible. Thanks for all your support.
Technorati Tags: Silverlight 4,Datagrid,Twitter API,Silverlight Timer