How to use HttpWebRequest to send POST request to another web server in Silverlight?

by Naveen 10. March 2010 10:14

Download Sample Projects (114.64 kb)

Quite some time back I wrote about How to use HttpWebRequest to send POST request to another web server in ASP.Net applications. Now that a lot of silverlight applications are being developed, we have similar need to post data from silverlight applications. The concept is exactly the same that I used in ASP.Net. But there is little difference. Silverlight does not allow blocking synchronous requests. All web requests are asynchronous. That means we have little bit more book keeping to do and manage the thread contexts etc. to make sure that then requests complete and we need to do any UI work in call back methods, we stay in correct thread context.

To keep example simple, I am going to post two values to destination URL using POST method. In the attached project, on Slots.xaml page, I have added a simple button Submit Data. And in the event handler of this button, I initiated request to submit data to Default page of sample web application. The event handler for the click looks as below.


private void SubmitData_Click(object sender, RoutedEventArgs e)
{
 // Prepare web request...
 HttpWebRequest myRequest =
 (HttpWebRequest)WebRequest.Create("http://localhost/SilverGridWeb/Default.aspx");
 myRequest.Method = "POST";
 myRequest.ContentType = "application/x-www-form-urlencoded";
 myRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), myRequest);
}

This code is pretty much same as what I had in ASP.Net application. There is one difference. Instead of calling GetRequestStream method, you will need to call BeginGetRequestStream. This will initiate an asynchronous request. There are two parameters that are passed to this method. First is the callback method that needs to be called when this method completes. Second parameter is any object that you want to pass to callback method. So here I have passed my HttpWebRequest object itself.

Now lets look at what is this callback method GetRequestStreamCallback. I copied the function from Microsoft documentation itself and made some changes to fit my needs.


private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
 HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
 System.IO.Stream postStream = request.EndGetRequestStream(asynchronousResult);
 string strId = "My Id";
 string strName = "My Name";
 string postData = "userid=" + strId;
 postData += ("&username=" + strName);
 byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(postData);
 // Write to the request stream.
 postStream.Write(byteArray, 0, postData.Length);
 postStream.Close();
 // Start the asynchronous operation to get the response
 request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}

You can see that in callback method, I grabbed the request object that was passed as state to the method call. Then I constructed data that I need to pass with the request that needed to be sent as POST. And then made another async call BeginGetResponse to submit the data and get the response.

Now lets look at what is this callback method for response.


private void GetResponseCallback(IAsyncResult asynchronousResult)
{
 HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
 HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
 Stream streamResponse = response.GetResponseStream();
 StreamReader streamRead = new StreamReader(streamResponse);
 string responseString = streamRead.ReadToEnd();
 // Close the stream object
 streamResponse.Close();
 streamRead.Close();
 // Release the HttpWebResponse
 response.Close();
 Action<string> act = new Action<string>(DisplayResponse);
 this.Dispatcher.BeginInvoke(act, responseString);
}

void DisplayResponse(string msg)
{
 GainersText.Text = msg;
}

Again I passed original HttpWebRequest object to the call method as state. In the call back method, you can grab the request object and then call EndGetResponse to get the resonse stream.

Thread Context and Invalid cross-thread access error

You will notice that in GetResponseCallback method I have called BeginInvoke method on Dispatcher thread. This is very important if you are planning on doing any UI manipulation in the call back methods. The call back methods are invoked on a thread that are separate from the UI thread that initiated the request. So if you try to access any UI element in this callback you will get the following exception thrown.


An unhandled exception ('Unhandled Error in Silverlight Application 
Code: 4004    
Category: ManagedRuntimeError       
Message: System.UnauthorizedAccessException: Invalid cross-thread access.
   at MS.Internal.XcpImports.CheckThread()
   at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value, 
   Boolean allowReadOnlySet, Boolean isSetByStyle, Boolean isSetByBuiltInStyle,
   PropertyInvalidationReason reason)
   at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value)
   at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
   at System.Windows.Controls.TextBlock.set_Text(String value)
   at SilverGrid.Views.Stocks.GetResponseCallback(IAsyncResult asynchronousResult)
   at System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClassd.
    <InvokeGetResponseCallback>b__b(Object state2)
   at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, 
   ContextCallback callback, Object state)
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal
   (_ThreadPoolWaitCallback tpWaitCallBack)
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)     
') occurred in iexplore.exe [7532].

Therefore it is important that from the callback method, you invoke an action request on Dispatcher thread of UI.

Views: 89

Tags:

Silverlight

Silverlight Cross Domain Web Service Access Error - This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place

by Naveen 9. March 2010 08:37

Here is some error that most of Silverlight developers run into at some point.


An error occurred while trying to make a request to URI 
'http://nave-pc/SilverGridWeb/GridDataService.asmx'.
This could be due to attempting to access a service in a cross-domain way 
without a proper cross-domain policy in place, or a policy that is unsuitable 
for SOAP services. You may need to contact the owner of the service to publish 
a cross-domain policy file and to ensure it allows SOAP-related 
HTTP headers to be sent. This error may also be caused by using internal types 
in the web service proxy without using the InternalsVisibleToAttribute attribute. 
Please see the inner exception for more details.

I had developed cross-domain access web services for Silverlight in the past and all work like a charm. This morning I ran into this issue again while developing a new web service for a new Silverlight application. I knew that I needed to add CrossDomain.xml or ClientAccessPolicy.xml at root of my web application. So I copied those files from existing application to this new one. To my surprise it did not resolve the issue. I tried all kind of tricks and options but nothing seemed to help. Finally I decided to look at Silverlight documentation and see if there is anything new that has been done for Silverlight 3. Last time I did this was for a Silverlight 2.0 application. I could not find anything different in the description of what needed to be done. But then there was something in the sample XML file content for these files that caught my eye and looked different that what I had.


<allow-from http-request-headers="SOAPAction" >

Notice the underlined section. Previously the value in the allowed headers used to be *. Well, that does not seem to work any more. So I replaced it and everything worked fine.

There are some other important points I am going to discuss in this post. A lot of users do not seem to be clear where these cross domain policy files should be placed.

Location of CrossDomain.xml and ClientAccessPolicy.xml

As the documentation states, these should be placed at the root of the application. Although the statement is very clear but it causes lot of confusion about what is root? There are two ways you create a site in IIS, Virtual Directory and Web Application. So if you have a web site foo.com created as a web site in IIS, then the folder containing the content of this site is root of the application. So your policy files go in that folder. If you have created a virtual directory Bar under this web site where your web service is hosted, then the root of the site is still foo.com and not foo.com/bar. To verify it, open IIS log of your application and look for entries for Crossdomain.xml and ClientAccessPolicy.xml. From those entries you can figure out where those files should be located. If the caller is not finding those files, then you should 404 errors in your log file. For example here are entries from my log file.


1.17.30.170 GET /clientaccesspolicy.xml - 80 - 1.17.30.162  404 0 2 1
1.17.30.170 GET /crossdomain.xml - 80 - 1.17.30.162 404 0 2 1

This is very important. If you are hosting your web service in a web application that is created as a virtual directory in Default Web Site then you need to copy these files in wwwroot folder or whatver folder is configured to be default folder for your IIS installation. Copying policy files in your virtual directory is not going to help. You can also verify the location by looking at traffic in fiddler for your web service access.

Content for CrossDomain.xml and ClientAccessPolicy.xml

I have copied the content of these two files below. These files work for me on my my servers for cross domain access from silverlight.

ClientAccessPolicy.xml


<?xml version="1.0" encoding="utf-8"?>
<access-policy>
	<cross-domain-access>
		<policy>
			<allow-from http-request-headers="SOAPAction ">
				<domain uri="*"/>
			</allow-from>
			<grant-to>
				<resource path="/" include-subpaths="true"/>
			</grant-to>
		</policy>
	</cross-domain-access>
</access-policy>

CrossDomain.xml


<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
	<allow-http-request-headers-from domain="*" headers="SOAPAction,Content-Type"/>
</cross-domain-policy>

Views: 67

Tags: , ,

Silverlight | WCF | Web Service

How to display custom tool tips in Silverlight Charts?

by Naveen 3. March 2010 11:49
custom tool tip in silverlight charts

Download Sample Projects (28.22 kb)

In my previous post, How to set silverlight column chart style programatically", I discussed one of the customizations of chart styles. In this post I will discuss one more customization of Silverlight charts rendering. This is about customizing display of Tooltip display on charts. If you look at default tool tip display, they are limited to displaying some combination of Independent and Dependent value. In some cases, that information is sufficient. But you may have cases where you want your tool tips to be verbose to convey more information about the data point that was used to render that point or column etc.

Template is the key

First and foremost concept that you will need to understand is how a chart actually gets rendered. Who decided the layout of various components of a chart display. Like any other Silverlight control, its the control template that defines how to chart is going to be rendered. So to customize the dispplay of Silverlight control, you can create a new template or take the default template and make modifications to it to come up with your own display scheme. Now you are asking from where can you get the default template for various chart types. The answer to it is Silverlight Toolkit source code. If you look in Charting/DataPoint folder of Controls.DataVisualization.Toolkit project, you will find template files for all chart types.

Customize Tooltip For Chart

Let us get started. For this discussion I picked Column type chart. Here are the steps that I followed to create a new template file for my column charts.

  • Add a new resource dictionary file in your project. In sample project I added ColumnChartStyle.xaml file under Assets folder.
  • Open ColumnDataPoint.xaml file from DataPoint folder from tool kit source. Copy the content of this file into your resource file.
  • Make sure that you change the build action of your resource file to Resource from Page
  • Assign a key to your style as shown below. You can pick any unique name. You are going to use the key when we apply this new template and style to our column charts.
    
    <Style TargetType="charting:ColumnDataPoint" x:Key="ByteBlocksColumns">
    
    
  • Open the XAML file where you have added chart that you want to display. In the sample project, it is in Home.xaml. And then assign DataPointStyle property to point to the static resource that we created from default implementation of ColumnDataPoint. And make sure that you use the key name that you used in the resource file. Following snippet shows how I did it in sample project.

    
    <chartingToolkit:Chart Title="Fruit Supply and Demand" 
       x:Name="FruitChart" 
       Width="500" 
       Height="350">
     <chartingToolkit:Chart.Series>
      <chartingToolkit:ColumnSeries
    		DataPointStyle="{StaticResource ByteBlocksColumns}"
            Title="Fruit Supply"
            IndependentValueBinding="{Binding Name}"
            DependentValueBinding="{Binding Supply}"/>
      </chartingToolkit:Chart.Series>
    </chartingToolkit:Chart>
    
    

Now you should be able to compile and run your project. We have not done any customization of tool tip yet. At this point you should be able to run the project with default template.

TooltipService and Tooltip

If you look near bottom of ColumnChartStyle.xaml file, you will find following snippet of code.


<ToolTipService.ToolTip>
 <ContentControl Content="{TemplateBinding FormattedDependentValue}"/>
</ToolTipService.ToolTip>

This is default implementation of how and what is displayed in tool tip. So you can see that by default only DependentValue is displayed. So this is the place where you will need to make changes to customize the display of tooltip for chart. If you are only interested in making some minor changes like adding some static text or adding display of dependent value as well, you can make a change as below.


<ToolTipService.ToolTip>
 <StackPanel Orientation="Horizonal">
 <ContentControl Content="{TemplateBinding FormattedDependentValue}"/>
 <TextBlock Text="-" />
  <ContentControl Content="{TemplateBinding FormattedIndependentValue}"/>
 </StackPanel Orientation="Horizonal">
</ToolTipService.ToolTip>

Customizing Tooltip Display at run time

In the sample project, I have implemented a use case where I want to create tool tip display at run time. What this means is that content of tool tip is being constructed based on some input from the existing data that is bound to that column. So in the template I am going to make some changes as shown below.


<ToolTipService.ToolTip>
<StackPanel Orientation="Horizontal">
<ContentControl Content="{Binding Id, Converter={StaticResource FruitConverter}}"/>
</StackPanel>
</ToolTipService.ToolTip>

In the snippet above you will see use of two things. One is that I am binding the content to the actual data object that was used to render that point. Second is use of converter. I am passing "Id" of the object as parameter to the converter. And in the converter I do some mock query to get more data. Following code shows how I constructed text of tool tip.


public class FruitSupplyToolTipConverter : IValueConverter
{
 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 {
  return GetToolTip(int.Parse(value.ToString()));
 }

 public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 {
  return value;
 }

 object GetToolTip(int id)
 {
  var supply = MockData.FruitSupply.GetSupply();
  var query = from item in supply where item.Id == id select item;
  var items = query.ToList();
  if (items.Count == 0)
  {
   return string.Empty;
  }
  return CreateToolTip(items[0]);
 }

 object CreateToolTip(FruitSupply supply)
 {
  var panel = new StackPanel();
  panel.Orientation = Orientation.Vertical;
  var tipTextBlock = new TextBlock();
  tipTextBlock.Inlines.Add(new Run { Text = supply.Name });
  tipTextBlock.Inlines.Add(new LineBreak());
  tipTextBlock.Inlines.Add(new Run { Text = string.Format("Supply: {0}", supply.Supply)});
  tipTextBlock.Inlines.Add(new LineBreak());
  panel.Children.Add(tipTextBlock);
  var hlink = new HyperlinkButton();
  hlink.Content = "For more informattion Goto http://www.ByteBlocks.com";
  hlink.NavigateUri = new Uri("http://www.byteblocks.com");
  panel.Children.Add(hlink);
  return panel;
  }
}

You could argue that instead of going to the extent of using converter to build a tool tip text, I could have added another property to data object that contains the text and then bind tool tip to that property. That would have worked perfectly as well. But for demonstrating how you can construct tool tip text based on some other pieces of data or if tool tip content changes rapidly with time as well, then you need to access it at run time.

I hope this should give you good starting point to go nuts on more nifty tool tips.

Views: 148

Tags: , ,

Charting | Silverlight

How to add paging to DataGrid in Silverlight

by Naveen 24. February 2010 10:23

Download Sample Project (367.89 kb)

paging in silverlight datagrid

In one of my previous posts How to use DataGrid in Silverlight I showed a very simple usage where data grid was bound to a list of products. Now let us take one more step in customizing use of this data grid. When I executed my method to get list of products from AdventureWorks database, it returned me about 1000 records. And then datagrid was bound to that list, i got a huge page with grid showing all the records. I am sure at this point you are looking for way to add some kind of paging to your data grid so that user can navigate the list easily.

Silverlight has a control named DataPager that comes in very handy to add paging functionality to any control that you use to display lists. From the name is it obvious that this control is a pager. Following XAML shows how I added paging functionality to my datagrid.


<StackPanel x:Name="ContentStackPanel" Orientation="Vertical">
 <TextBlock x:Name="HeaderText" Style="{StaticResource HeaderTextStyle}" 
     Text="Products"/>
  <data:DataPager x:Name="ProductsPager" 
    PageSize="10" 
    DisplayMode="Numeric" 
    AutoEllipsis="True" 
    HorizontalAlignment="Left" />
  <data:DataGrid x:Name="ProductsGrid">
   <data:DataGrid.Columns>
   <data:DataGridTemplateColumn>
   <data:DataGridTemplateColumn.CellTemplate>
   <DataTemplate>
   <StackPanel>
   <Button x:Name="UpdateButton" Content="Update" 
     Click="UpdateButton_Click"></Button>
   </StackPanel>
   </DataTemplate>
   </data:DataGridTemplateColumn.CellTemplate>
   </data:DataGridTemplateColumn>
   </data:DataGrid.Columns>
   </data:DataGrid>
</StackPanel>

You can read more about different ways to customize the display of datapager from the documentation. For this discussion you can see that I have set PageSize, DisplayMode, AutoEipsis and HorizontalAlignment properties of pager and the screen shot shows how it looks. I will talk more about customization of DataPager in detail in next post. For now I just want to keep it to simple use.

PageViewCollection

This is the collection object that drives the functionality for DataPager. In general you need a collection that implements IPagedViewCollection interface. No, you do not have to do any more implementation to get DataPager to work. We already have list of products obtained from previous web service call. You can simply wrap that list into PagedViewCollection object and set it as Source for DataPager object. And then set the source for DataGrid as this PagedViewCollection object and we are all set to go. Following code shows simple change I made in code from previous sample project.


void GetProductsCompleted(object sender, GetProductsCompletedEventArgs e)
{
 _products = e.Result;
 if (null != _products)
 {
  _pagedProductsView = new PagedCollectionView(_products);
  ProductsPager.Source = _pagedProductsView;
  ProductsGrid.ItemsSource = _pagedProductsView;
 }
}

Add References

PagedViewCollection is defined in System.Windows.Data assembly. So you will need to add reference to this assembly in your Silverlight project and then add using directive for the namespace in your source code to refer to the classes in this namespace and assembly.

Adding Paging to DataGrid in Silverlight is as easy as that.

Views: 197

Tags: ,

DataGrid | Silverlight

How to add buttons to Silverlight DataGrid?

by Naveen 11. February 2010 15:36

Download Sample Project

In the previous post How to use Silverlight DataGrid I discussed simple use of DataGrid in Silverlight application. Now it is time to start putting together implementation that we have from day to day to applications. One of the tasks that you may come across is that you need to add buttons to each row in the DataGrid and then handle click events for those buttons. In the previous post I mentioned use of DataGridTemplateColumn to provide custom rendering of columns in the grid. So to add button(s) to your column, you will use the template column and then provide Button control to add them to each row. Following snippet shows how it looks like in my sample application.


<data:DataGrid x:Name="ProductsGrid">
 <data:DataGrid.Columns>
  <data:DataGridTemplateColumn>
  <data:DataGridTemplateColumn.CellTemplate>
   <DataTemplate>
    <StackPanel>
     <Button x:Name="UpdateButton" Content="Update" 
        Click="UpdateButton_Click"></Button>
    </StackPanel>
   </DataTemplate>
  </data:DataGridTemplateColumn.CellTemplate>
 </data:DataGridTemplateColumn>
 </data:DataGrid.Columns>
</data:DataGrid>

Handling Click Event For Button In DataGrid

As you can see from the XAML above, I just added handling of Click event on Button control. And in the codebehind provided implementation for it.


private void UpdateButton_Click(object sender, RoutedEventArgs e)
{
 var ctl = e.OriginalSource as Button;
 if (null != ctl)
 {
  var product = ctl.DataContext as Product;
  if (null != product)
  {
   var msg = string.Format("{0}, {1}, {2}", 
      product.ProductID, product.Name, product.ListPrice);
   MessageBox.Show(msg);
  }
 }
}

Accessing Data Associated With Row In DataGrid

When user clicks on the button in datagrid row, the method gets called. Next question you have is how do you access the data associated with the row on which button was clicked. It is very straight forward. When DataGrid rendering takes place, each control in the row is bound to DataContext. This DataContext is the data that was used to render that row. So you simple look at DataContext property of Button control that raised the event and got the actual data object used for that row.

I think this should give you a good starting point on how to add buttons or some other controls in DataGrid rows and how to access data for them as well. In next post I will discuss more of customization of Silverlight DataGrid.

Views: 377

Tags: ,

DataGrid | Silverlight

How to use DataGrid in Silverlight

by Naveen 5. February 2010 06:58
DataGrid is one of the most important control when it comes to displaying tabular kind of data. We all implement rendering of such data in some of table format. Developers who has been using ASP.Net are very familiar with controls like DataGrid and GridView. Good news is that there is equivalent DataGrid control for Silverlight as well. And for most part it is used the same way as you do in ASP.Net but with different syntax and different way of customizing display of it. In this post I am going to show a very plain and simple use of DataGrid control in Silverlight and then in subsequent posts I will build on top of this post to show some more advanced uses of DataGrid control.

Silverlight Tool Kit

You may already know this and already has it on your development machine, but I will mention it for sake of completness. You are going to need Silverlight Toolkit to use DataGrid. Yes, the control is not part of core Silverlight. Microsoft has developed it as part of the tool kit that has lot of usefull controls. You can read more about this tool kit and controls on the site. For now, down the toolkit and install it on your machine.

Reference assemblies

In your Silverlight project, you will need to add reference to System.Windows.Controls.Data assembly. This is the assembly where DataGrid control is defined. Now you can include DataGrid control on your XAML file. If you tried to add mark up like below on your page, you are going to get error telling you that DataGrid is not recoganized.


<DataGrid x:Name="MyGrid" />

You have to treat DataGrid control like a UserControl in ASP.Net where you have to specify a tag prefix and assembly on top of your page to indicate use of that control. In Silverllight you do this my including xml namespace tag for that silverlight control. In my case I have the following xmlns entry on my XAML file.


xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"

This tells the application that I am going to use prefix data for the controls that are present in assembly System.Windows.Controls.Data. Based on this you can now add the following like of mark up on XAML file to include DataGrid on your page.


<data:DataGrid 
  x:Name="CommentsGrid" 
  Height="300" 
  AutoGenerateColumns="True" 
  IsReadOnly="True">
</data:Grid>

Attach To Data Source

Now that we have included DataGrid control on the page, we need to attach it to some data source to show some results. Very much like ASP.Net, you will attach an enumeration to this control. The difference is that here it is done through property name ItemSource. Following line of code shows how it is done for silverlight DataGrid control.


List<Comment> unmoderatedComments = new List<Comment>();

void BindGrid()
{
 CommentsGrid.ItemsSource = unmoderatedComments;
}

As you can see that DataGrid is bound to a List of Comment objects. So far so good, very much like your ASP.Net DataGrid or GridView.

Columns to Display

In the mark of DataGrid above, I have explcitly set AutoGenerateColumn property to true. This actually is default value. What this means is that when DataGrid is bound to the collection, it will generate column for each data field or property for the objects in the collection and display them. Thsi is same behavior you see in ASP.Net data grid.

Explcitly specifying Columns

When you are dealing with some real application most of the time you control the columns you want to display and how you want to display them. Silverlight DataGrid does allow you to do so. Fisrt, you will set AutoGenerateColumns property to false. Following mark up shows how you will specify the columns that you want to display.


<data:DataGrid x:Name="CommentsGrid" Height="300" 
  AutoGenerateColumns="False" IsReadOnly="True">
 <data:DataGrid.CellStyle>
  <Style TargetType="data:DataGridCell">
  <Setter Property="VerticalAlignment" Value="Top"></Setter>
  </Style>
 </data:DataGrid.CellStyle>
 <data:DataGrid.Columns>
  <data:DataGridTextColumn Header="Comment Date" 
    Binding="{Binding CommentDate}"></data:DataGridTextColumn>
  <data:DataGridTextColumn Header="Comment Text" Binding="{Binding Text}">
  <data:DataGridTextColumn.ElementStyle>
  <Style TargetType="TextBlock">
   <Setter Property="TextWrapping" Value="Wrap"/>
  </Style>
  </data:DataGridTextColumn.ElementStyle>
 </data:DataGridTextColumn>
 <data:DataGridTemplateColumn>
  <data:DataGridTemplateColumn.CellTemplate>
   <DataTemplate>
    <StackPanel Orientation="Horizontal">
     <Button x:Name="ApprovedButton" Content="Approved" 
       Click="ApprovedButton_Click" Height="30" Margin="3"></Button>
     <Button x:Name="DeleteButton" Content="Delete" 
        Click="DeleteButton_Click" Height="30" Margin="3"></Button>
     <Button x:Name="SpamButton" Content="Mark Spam" 
       Click="SpamButton_Click" Height="30" Margin="3"></Button>
   </StackPanel>
   </DataTemplate>
  </data:DataGridTemplateColumn.CellTemplate>
 </data:DataGridTemplateColumn>
 </data:DataGrid.Columns>
</data:DataGrid>

You will need to add Columns section under your DataGrid control definition and then specify each column that you would want to display. And to bind the column to particular property or field, you will use Binding property. For this post I am going to keep the dicussion to simple binding of the column to property of the object. I will discuss more advanced use in subsequent posts. You can see it is very similar to how you are used to doing things in ASP.Net.

And to accomodate more customized view of the column, you will use DataGridTemplateColumn where you can layout the template of the view of that column. This is also similar to template column in ASP.Net.

More...

For this post I am going to leave this discussion to this simple display of data. I will be discussing more about use of Silverlight DataGrid in subsequent posts. This post should get you started with use of it now.

Views: 442

Tags: ,

DataGrid | Silverlight

How to hide navigation controls on Bing Map Silverlight control

by Naveen 7. January 2010 17:25

Default rendering of Bing Map Silverlight Control displays few of the in-built controls like Copyright, Scale, Navigation, Logo etc. If you are not interested in displaying any of these controls, you can simply hide it by setting their visibility. Following code snippet shows how to hide these navigation controls.


void SetMapForgroundMembers()
{
 UserLocationsMap.NavigationVisibility = System.Windows.Visibility.Collapsed;
 UserLocationsMap.LogoVisibility = Visibility.Collapsed;
 UserLocationsMap.CopyrightVisibility = System.Windows.Visibility.Collapsed;
 UserLocationsMap.ScaleVisibility = System.Windows.Visibility.Collapsed;
}		}

Views: 517

Tags: ,

Silverlight

How to use Bing Map Silverlight Control and add push pins for location markers

by Naveen 6. January 2010 07:35
Bing map silverlight control sdk

In one of my earlier posts Convert IP Addresss To Geo Location, I discussed how you can query a web service or database to get geo-location of that internet service provider. Now what do you do with that geo-location or spatial information. For one of the current Data Visualization projects I am working on, I had to show these locations on the map as well. The application is a Silverlight application so obvious choice was to find a control or component that I could drop in silverlight. And you pretty much have the answer, Use Bing Map Silverlight Control.

In this post I am going to discuss some of the following topics.

  • How to use Bing Silverlight Map Control?
  • How to add push pins to bing map?
  • How to add legends or some text to Silverlight Bing Map?
  • How to add regular silverlight controls on Bing Map control?

The documentation for Bing Map Silverlight control is still maturing and lacks lot of details. So most of the discussion in this post is based on personal experience and conversations I had through news groups and forums.

Set up development enviroment

Before you can start developing your silverlight application using Bing Map Silverlight control, you will need to do following things.

  • Create a developer account at Bing portal
  • As part of registration process, you will also be required to a credential key that is used with each request that you send to Bing web service to access data.
  • Download Bing Map Control SDK and install on your development machine.

Create Project and lets roll

Microsoft has provided a good walk through on Creating a Basic Application Using the Silverlight Map Control. I will strongly recomment going through it if its first time for you in Bing Map development.

Adding PushPin to Bing Map

Now that you have a vanilla implementation of map showing in your application. Next I want to add indicztors on the map to show location of internet service providers for which I have geo corodinates. There are few ways you can do. The most basic thing that you need to keep in mind is that Bing Map control is like any other silverlight control and can act as a container for other silverlight control. That means that I can just draw any shapes or objects at given corodinates. Well, you got it. Bing Map SDK provides some of these indicator controls out of the box. And one of them is PushPin. So what you need to do is crate instances of PushPin objects, set their longitude and latitude and add them as children of map control. Following code snippet shows how I added a collection of PushPin objects to my map control.

foreach(var loc in locations)
{
	var pp = new Pushpin() 
	  {Location = new Location(loc.Latitude, loc.Longitude)};
	UserLocationsMap.Children.Add(pp);
}

Adding DataGrid to Bing Map

Next task I had to do was to provide some summary of the data on the map itself. More precisely, I wanted to show how many service provides from each country I have in my database. For demo purposes I just needed to show name and count. I decided to add a DataGrid to map to show this data. Later on I am going to handle click events in this grid to have some interaction with the map as well. Since I already knew where I wanted to place the grid and what columns needed to be shown, I could just add this through XAML file itself. Following XAML snippet from the application shows how I have added a text block and data grid to Bing Map control as children.


<m:Map CredentialsProvider="xxxxxxxxxx" Name="UserLocationsMap">
 <m:Map.Children>
  <o:ShadowText x:Name="MapTitleText" ForegroundTop="Black" ForegroundBottom="Orange"
      Text="ISP Locations" FontFamily="Verdana" FontSize="24"
      HorizontalAlignment="Left" Margin="20,75,50,10"/>
	<StackPanel x:Name="CountryListPanel" Margin="20,250,50,10" Orientation="Vertical">
	 <data:DataGrid x:Name="CountryCountGrid" Width="150" Height="250"
	   AutoGenerateColumns="False" HorizontalAlignment="Left">
	  <data:DataGrid.Columns>
	   <data:DataGridTextColumn Header="Country" Width="SizeToHeader" Binding="{Binding Name}" />
	   <data:DataGridTextColumn Header="Count" Width="SizeToHeader" Binding="{Binding Count}" />
	  </data:DataGrid.Columns>
	 </data:DataGrid>
	</StackPanel>
	</m:Map.Children>
</m:Map>

Postioning on Map control

This is something you will have to play very close attention to. There is a difference between how controls or objects placed on map control. You must have noticed that when I added PushPin to map, I used longitude and latitude to position them on the map. But when I added DataGrid and ShadowText controls, I used Margin to control the placement. Most of the indiccator or layer objects that are provided in Bing Map SDK use gro-location values (longitude and latitude) to place object. But when you add regular silverlight controls on map, then you will control the position using Margin relative to origin of map control.

Views: 1418

Tags: ,

Bing Map | Silverlight

How to set silverlight column chart style programatically

by Naveen 4. January 2010 14:31

Let me wish a happy new year to all our blog readers.

This is first post of year 2010 and I decided to write my favorite topic of all times, Data Analysis and Visualization. These days I am working on a Silverlight application that involves very extensive use of charts for data visualization. And I use charting controls provided by Microsoft in Silverlight tool kit.

There are lot of examples available out there that shows you how to use these controls and how to style them. When it comes to styling and things like that, majority of the examples are focused around modifying control template or modifying styles in XAML file itself. Lot of time you make decisions about the type of chart and style of chart at run time based on data that needs to be visualized.

In this post I am going to focus on following tasks:

  • How to add a chart series programatically
  • How to set style of chart series programtically
  • How to set colors of columns in silveright charts programtically

Following image shows you a multi-series column chart. It shows three types of values at different intervals. One of the driving factor behind adding the column series was that I did not know how many different types of values are going to be returned in the data. So I could not simply add X number of ColumnSeries on XAML to say that I need to draw multi-series column chart with 3 points or things like that.

silverlight multiseries column chart

Following code snippet shows how I added column series in the main chart controls and how I specified different colors of the bars that are going to represent each type of data point.


foreach(LatencyColumnPlotData plotData in _latencyDataValues.ColumnPlotValues)
{
var series = new ColumnSeries();
var style = new Style(typeof (ColumnDataPoint));
SolidColorBrush bgBrush = (idx==1) ? 
    new SolidColorBrush(Colors.Blue) : 
    new SolidColorBrush(Colors.Orange);
var setterBg = new Setter(ColumnDataPoint.BackgroundProperty, bgBrush);
style.Setters.Add(setterBg);
series.DataPointStyle = style;
series.ItemsSource = plotData.DependentValues;
series.IndependentValueBinding = null;
series.Title = (idx == 1) ? "Average" : "Current";
idx++;
latencyChart.Series.Add(series);
}

var thresholdSeries = new ColumnSeries();
thresholdSeries.IndependentValueBinding = null;
thresholdSeries.ItemsSource = _latencyDataValues.ThresholdLatencyValues;
thresholdSeries.Title = "Threshold";
var bg = 
   new Setter(ColumnDataPoint.BackgroundProperty, new SolidColorBrush(Colors.Green));
var bgStyle = new Style(typeof(ColumnDataPoint));
bgStyle.Setters.Add(bg);
thresholdSeries.DataPointStyle = bgStyle;
latencyChart.Series.Add(thresholdSeries);

Views: 1200

Tags: , ,

Silverlight

How to set axis properties programatically for Silverlight charts

by Naveen 7. December 2009 06:23

In my previous post How to hide gridlines in charts, I showed how you can accomplish the task from XAML. This is all good when you know that rendering behavior of you chart is not going to change or you do not have to modify the display at run time based on some computed values curing run time. And works great for design time as well. But a lot of time you want to change the behavior at run time. In that case you need to know how you can change properties of axis programatically.

Each chart has a collection of Axis. By default this collection is empty. Charting controll fills this collection if you do not provide any. And it makes it decision based on the type of values you render on these axis. For example tf you are displaying DateTime type values on an axis, control will add DateTimeAxis to its collection. I have two liner axis in my chart that display simple numeric values. Following code shows how I added two linear axis, X and Y, to my chart. Most important property to set is Orientation. Without it, rendering engine does not know what axis you intend to change.


private void SetYAxis()
{
  var lax = new LinearAxis();
  lax.ShowGridLines = false;
  lax.Orientation = AxisOrientation.Y;
  lax.Title = "Response Time";
  myChart.Axes.Add(lax);
}

private void SetXAxis()
{
   var lax = new LinearAxis()
              {
                ShowGridLines = false,
                Title = "Interval",
                FontWeight = FontWeights.Bold,
                MaxHeight = 1,
                Opacity = 0,
                Orientation = AxisOrientation.X
               };
   myChart.Axes.Add(lax);
}

Views: 828

Tags: , ,

Silverlight | Charting

How to hide grid lines in Silverlight chart?

by Naveen 7. December 2009 05:53

This is one of the thing that is easy to do but no so obvious. I think mostly its lack of complete description of how charting controls provided in Silverlight toolkit work and how to manipulate them. When you draw charts like Line, Column, Bar etc., the grid line on DependentValue are rendered by default. There is a property ShowGridLines available on DisplayAxis class that is base class for axis. You just need to set its value to False. For example in my line chart I did not want to show grid lines on grid lines on Y axis. Following XAML snippets shows how I turned off rendering of grid lines on Y-axis.


<chartingToolkit:Chart Title="Latency" x:Name="latencyChart" BorderThickness="1">
 <chartingToolkit:Chart.Series>
  <chartingToolkit:LineSeries Title="Val 1" 
     DependentValueBinding="{Binding Threshold}"
     IndependentValueBinding="{Binding IndependentValue}" 
     AnimationSequence="Simultaneous" />
  <chartingToolkit:LineSeries Title="Val 2Latency" 
   DependentValueBinding="{Binding Current}" 
   IndependentValueBinding="{Binding IndependentValue}" 
   AnimationSequence="Simultaneous" />
  <chartingToolkit:LineSeries Title="Val 3" 
   DependentValueBinding="{Binding Average}" 
   IndependentValueBinding="{Binding IndependentValue}" 
   AnimationSequence="Simultaneous" />
  </chartingToolkit:Chart.Series>
   <chartingToolkit:Chart.Axes>
    <chartingToolkit:LinearAxis Orientation="Y" ShowGridLines="False"/>
  </chartingToolkit:Chart.Axes>
</chartingToolkit:Chart

Views: 832

Tags: , ,

Charting | Silverlight

Silverlight compile error - The tag 'Label' does not exist in XML namespace

by Viper 8. October 2009 05:55

I was working on a silverlight form in an application. I was trying to add some validations and other related controls on the page. So I had added Label control on the page. I declared the xml namespace and associated tags at the top of the control file as well. When I tried to compile the application, I got the following error. I looked at the declarations, my SDK folder to make sure that I have the required SDK assemblies, I looked in GAC etc. Everything looked good and I still could not figure out what the problem is.

The tag 'Label' does not exist in XML namespace 'clr-namespace:System.Windows.Controls;assembly= System.Windows.Controls.Data.Input'
Could not load type 'Microsoft.Windows.Design.DataContextValueSourceAttribute' from assembly 'Microsoft.Windows.Design.Interaction, Version=3.7.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

What is the problem?

After spending good bit of time, I decided to look at one of the sample in SDK. I still could not figure out the issue. Then I decided to copy and paste the xml namespace and tags from the sample to my XAML file. Now everything worked fine. When I closely looked at the declaration, I saw the issue. See below, the one in red is wrong and one in green is good.

xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly= System.Windows.Controls.Data.Input"

xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input"

You can see I had an extra white space after assembly=. It seems that compiler is literally parsing the string and trying to look for assembly file with name as is in the statement. Instead of giving error message that some namespace or control does not exist in the assembly, the correct error message should have been that assembly with name or path could not be found. I could not complain much either because I am using Visual Studio 2010 Beta and beta version has lot of room for improvement.

Views: 1421

Tags:

Silverlight | Visual Studio

How to implement OWA style new message notifier poup using Silverlight and javascript

by Viper 6. October 2009 14:06
OWA style new message notification popup

Download Demo Projects

This is one of the projects I have been planning to work on for some time. I was looking into building an event notifier in one of my ASP.Net application. I wanted it to be more like Outlook Web Access (OWA) new email notifier pop-up. It is the one that slides up from bottom right corner of your browser when there is a new email in your inbox. I had built it in the past using all javascript solution. Yes, this Microsoft is one of the earliest implementation of so called AJAX applications. I did not want to deal with all the javascript code related to setting up HTTP calls and then dealing with response and rendering the results.

I wanted to leverage Silverlight to do all the heavy lifting. And use light weight javascript implementation on client to do animated sliding and positioning of the popup notifier box. At the end it turned out be quite an elegant solution that worked on major browsers like Internet Explorer, FireFox and Chrome. This article is an attempt to describe How to implement OWA style new email notifier popup using Silverlight and Javascript.

The implementation involved the following technologies and I will describe how each component was implemented

  • ASP.Net web application
  • ASP.Net web service
  • Silverlight application

ASP.Net Web Service

Let's start with discussion of the component that is responsible for communication of data between client and server application. The client requests data from server at certain frequency to check if there are any new messages. So I implemented as simple ASP.Net web service application with few web methods. For this demo I had a simple method with following signature.


[WebMethod]
public string GetGlobalMessages()
{
 List msgs = MockData.GetGlobalMessages();
 return msgs.ToJson();
}

For demo application, I implemented a MockData class that creates a random list of messages and then serializes that collection as JSON and sends it in response. I implemented ToJson as an extension method on List<StatusMessage> object. You will find it in Extension.cs file in ActivityData project.


public static string ToJson(this List<StatusMessage> msgs)
{
 var ser = new DataContractJsonSerializer(msgs.GetType());
 var ms = new MemoryStream();
 ser.WriteObject(ms, msgs);
 var serializedData = System.Text.UTF8Encoding.UTF8.GetString(ms.ToArray());
 return serializedData;
}

You can see there is nothing fancy about this whole implementation to make it work with a Silverlight client. A very simple ASP.Net web service.

Silverlight Application

This is where all the action happens. There are few components of this application, rendering and data access. Lets us first discuss data access. The client application is to talk to server at certain frequency. That means I need some kind of timer going in the application. When this timer ticks at specified interval of time, it send asynchronous request to server to get new messages. I have implemented this whole mechanism in MessageMonitor application. When this class is constructed, it creates an instance of DispatchTimer. You may be asking why DispatchTimer and why not simple Timer application. The problem is that when you are dealing with user interface application, you can only update the controls on the thread on which they were dispatched. Regular timer does not executes on that dispatcher thread. So if you will try to update your user interface on that thread you will get exception complaining about cross threaded access. Here is the code that created DispatcherTimer for my application.


private void CreateMessagePollTimer()
{
 _messagePollTimer = new DispatcherTimer();
 _messagePollTimer.Tick += new EventHandler(MessagePollTimer_Tick);
 _messagePollTimer.Interval = new TimeSpan(0, 0, MessagePollInterval);
}

When the timer ticks it calls MessagePollTimer_Tick method. And that method makes async request to server to get new messages.


void MessagePollTimer_Tick(object sender, EventArgs e)
{
 if (Stopping || MessagePollInProgress) return;
 GetMessages();
}

When async request to server completes, the following method gets called. You can see that now it uses the same JsonSerializer class to de-serialize the response into list of StatusMessage objects. And then it raises event for objects that have subscribed to the event.


void GetGlobalMessagesCompleted(object sender, 
  SiteMessagePanel.ActivityDataServices.GetGlobalMessagesCompletedEventArgs e)
{
if (e.Error != null)
{
 return;
}
 var msgsData = e.Result as String;
 var msgs = msgsData.FromJson();
 System.Diagnostics.Debug.WriteLine(msgs);
 StatusMessageEventArgs args = new StatusMessageEventArgs(msgs);
 OnStatusMessageReceieved(args);
}

Page class that implements user interface for popup, handles this event and renders all the messages.


void Monitor_StatusMessageReceieved(object sender, 
 ByteBlocks.ActivityData.StatusMessageEventArgs arg)
{
 if (arg.Messages.Count == 0)
 {
 msgTextBlock.Text = "No messages received";
 ShowClientPanel(false);
 return;
 }

 msgTextBlock.Text = string.Empty;
 messagesPanel.Children.Clear();
 foreach (var msg in arg.Messages)
 {
  StackPanel sp = new StackPanel();
  TextBlock tb = new TextBlock();
  tb.Text = msg.Title;
  tb.TextWrapping = TextWrapping.Wrap;
  sp.Children.Add(tb);
  messagesPanel.Children.Add(sp);
 }
 ShowClientPanel(true);
}

ASP.Net application and javascript

ASP.Net application acts as a host for the silverlight control that I created to render messages. I have implemented a simple Server Control that hosts it. Then I added that control inside a simple div on the master page. And I have very simple vanilla implementation of the server control. It does not have very complicated implementation. I simply copied the code generated by silverlight wizard for test page into that control


<div id="statusslideup">
<ByteBlocks:StatusPanel runat="server" id="statusPanel" />
</div>

Calling Javascript Method From Silverlight

So far we have implemented two pieces of the application that drive the data and render it. Now comes the fun part. How are we going to trigger the client to show the popup and animate it to come up from bottom. First, it is Silverlight application that is running the timer. So it is the one that has to trigger the client. I implemented some java script code that shows the DIV that hosts silverlight client component. And then small piece of code that implements animation. Silverlight framework provides a very simple mechanism to invoke any Javascript method that is implemented on client side. I implemented a very simple method in silvelight application to call my JS method whenever there are new messages for the user.


private void ShowClientPanel(bool show)
{
 HtmlPage.Window.Invoke("_showStatusPanel", show);
}

It could not be any simpler. And the following Javascript function implements small piece of code that calculates position of popup notifier window based on browser height and height of element containing silverlight control.


setStatusPanelPosition = function() {
 if (_statusdiv) {
 _maxPanelPos = document.body.scrollTop + ($(document).height() - _statusdiv.clientHeight);
 _curPanelPos = $(document).height();
 if (!_isStatusVisible) {
  _sliderInterval = setInterval("_slidePanel()", 5);
 }
 else {
  _statusdiv.style.top = _maxPanelPos + "px";
 }
 _isStatusVisible = true;
 }
}

Demo Project

Attached demo project is a collection of Visual Studio 2010 projects and solution. If you do not have VS2010, you can simply create a new solution and projects in VS2008 and copy the source files in there. You are also going to need to download Silverlight 3 Toolkit because I use theming controls from that toolkit to give some zing to the UI.

I hope this demo project helps you in building cooler implementations of OWA like message and event notifier windows.

Views: 2415

Tags: , ,

ASP.Net | Javascript | JQuery | Silverlight

How to send data from Javascript to Silverlight control to render charts

by Viper 31. July 2009 15:09

Download Demo Project

I have been discussing use of jQuery to send AJAX request to server to get some data every X number of seconds to get server time and calculate some latency numbers. Now it is time to add some color to it. The numbers that I am getting is great and provide some useful information. But having a visual of how these numbers are varying with time will enhance utility of these statistics. So I decided to add some charts to show these latency numbers are varying with time. In this article I am going to show how you can pass the data obtained from server using AJAX request to a Silverlight application hosted on the page. This silverlight application uses charting control from Silverlight toolkit. Lets see how all this fits together to get this to work.

Bridge between Javascript and Silverlight component

In one of earlier posts, How to setup communication between silverlight applications, I discussed how you set this bridge up. The sample project for that article was done using Silverlight 2. The mechanism to set up the communication bridge has not changed in Silverlight 3. So all those concepts still apply for this project as well. The following code snippets shows declaration of a method decorated with ScriptableMember attribute to let silverlight framework know that this methos is to be exposed to javascript. And in constructor of the page, HtmlPage.RegisterScriptableObject method is called to register the class to be exposed to javascript. I do not want to expose all my properties, fields and methods to javascript. So I have not added scriptable attribute on class itself. I want to control what is exposed and what is not.


public MainPage()
{
	InitializeComponent();
	HtmlPage.RegisterScriptableObject("ClockDataClient", this);
	SetupChartDisplay();
}
		
[ScriptableMember]
public void PutNewClockData(string xtx, string data)
{
	AddDataPointToPlot(data);
}

This completes what needed to be done from silverlight application to expose its end points to javascript. Now we are going to see what is done on pages to communicate to silverlight control.

Setting up the page

First thing you need on the page is to include your Silverlight control. On Default.aspx you will find the following declaration of object tag that will host the control.


<object id="clockDisplayPlugin" data="data:application/x-silverlight-2," 
  type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="ClientBin/ClockLatency.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="onLoad" value="onLoadClockDisplay" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="3.0.40624.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration:none">
  <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="" style="border-style:none"/>
</a>
</object>

All this code was generated by wizard when I added test paste to my project. I added a new param declaration to handle load event. This event is fired when Silverlight control has been loaded. On lets see what all javascript is required to send message to silverlight control.


function onLoadClockDisplay(sender, args) {
 objClockDisplay = sender.getHost();
}

function sendLatencyData(data) {
 if (null != objClockDisplay) {
  objClockDisplay.Content.ClockDataClient.PutNewClockData("", data);
 }
}

As you can see, in load event handler I saved the reference to Silverlight control object. Then from my ajax request code, every time I got the data from server, I call sendLatencyData method. This method calls PutNewClockData method that I exposed from control using ScriptableMember attribute. This call constitutes of four parts.

objClockDisplay.Content.ClockDataClient.PutNewClockData

objClockDisplay is reference to our silverlight plugin. Content is the property on plugin object through which control's methods are exposed. ClockDataClient is the key that was used to register the class as scriptable in our control. PutNewClockData is the name of the method.

Setting up charting control in Silverlight component

I used charting control from Silverlight Toolkit for my project. I decided to use column chart to display latency numbers over time. In silverlight application project, I added the following XAML on MainPage.


<chartingToolkit:Chart Title="Clock Latency" x:Name="latencyChart" BorderThickness="2">
 <chartingToolkit:Chart.Series>
  <chartingToolkit:ColumnSeries Title="Latency" DependentValueBinding="{Binding Latency}" AnimationSequence="Simultaneous" />
 </chartingToolkit:Chart.Series>
</chartingToolkit:Chart>

In codebehind i created a collection to save data sent from javascript and attached the column series to that collection. I only keep last 11 entries in the collection.


void SetupChartDisplay()
{
 ColumnSeries cs = latencyChart.Series[0] as ColumnSeries;
 foreach(var lItem in cs.LegendItems)
 {
  lItem.Visibility = System.Windows.Visibility.Collapsed;
 }

 latencyChart.Width = 500;
 (latencyChart.Series[0] as DataPointSeries).ItemsSource = DynamicCollectionItemsSource;
}

You can see it was pretty simple to set this whole up and get javascript to send data to silverlight control and render the charts using those numbers.

Click to see demo

Feel free to send any comments or suggestions.

Views: 1908

Tags: , ,

HTMLParser | JQuery | Silverlight

Could not load file or assembly 'System.Web.Silverlight' or one of its dependencies

by Viper 30. July 2009 11:41

This morning I was working on a prototype Silverlight application that I developed with Silverlight 2. I copied the project to my new shiny Dell XPS with GTX280 video card. Moment i hit F5 to debug the application, i get the following exception.

Could not load file or assembly 'System.Web.Silverlight' or one of its dependencies. The system cannot find the file specified
Line 2: <%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls" TagPrefix="asp" %>

It just took me by surprise. I was like, I did not change anything in the project in couple of months and I have new installation of all visual studio tools. After digging through release notes and documentation of Silverlight 3 SDK and tools, i found out that Microsoft has decided to get rid of ASP.Net Silverlight server control that was part of Silverlight 2 SDK. Since I have fresh install of Visual Studio 2008 and tool and I never installed Silverlight 2 SDK on this workstation, I did not have that server control.

Microsoft is recommending to use object tag to insert Silverlight components on the pages now. It is not big deal but it was nice having that server control do all the dirty work behind the scene for you and add object with appropriate parameters and other values. If you still want to continue using that Silverlight server control, you can copy System.Web.Silverlight assembly from other machine or you can install Silverlight 2 SDK.

There seem to be few issues with that ASP.Net server control but none are serious that you could not keep the control and use workaround to get over the issues.

Views: 4426

Tags:

Silverlight

Navigation frame in Silverlight applications

by Viper 19. May 2009 14:37

In silverlight versions prior to 2, we all were setting up navigation for application using work arounds like setting up a layout on a page that will look like a application frame then provide some links etc. on that page to mimic behavior of a navigation system. Well now you do not have to do that any more. Silverlight 3 has included Frame UI element that provides all the navigation facilities. This control is included in System.Windows.Controls.Navigation assembly. You will also notice new namespace System.Windows.Navigation in documentation that provides all the support needed for navigation features.

silverlight navigation pages

When you choose to add a new project to IDE, you will notice a new template for adding Silverlight Navigation Application to your solution. The wizard will generate all the necessary XAML and code to include a navigation frame and include three pages as part of the application. This will give you a good starting point to build a navigtion type Silverlight application.

Views: 389

Tags: ,

Silverlight

Running silverlight applications outside the browser with Silverlight 3

by Viper 19. May 2009 03:44

A long awaited feature for Silverlight, the capability to run silverlight applications without browser. A lot of clients have asked me in the past to build such solutions. They always looked at how Flash application were running on their desktop without it being hosted in browser. Finally Microsoft is delivering that capability in Silverlight 3. It is still in Beta 1 state, but it looks promising already. Here is what microsoft release notes say about this feature.

Out of Browser Capabilities. The new out of browser experience in Silverlight 3 enables users to place their favorite Silverlight applications directly onto their PC and Mac, with links on the desktop and start menu—all without the need to download an additional runtime or browser plug-in. Further, the new experience enables Silverlight applications to work whether the computer is connected to the Internet or not—a radical improvement to the traditional Web experience. Features include:

  • Life outside the browser. Silverlight applications can now be installed to and run from the desktop as lightweight web companions. Thus, users can take their favorite Web applications with them, regardless of whether they are connected to the Internet or not.
  • Desktop shortcuts and start menu support. Silverlight applications can be stored on any PC or Mac computer’s desktop with links in the start menu and applications folder, and so are available with one-click access.
  • Safe and secure. Leveraging the security features of the .NET Framework, Silverlight applications run inside a secure sandbox with persistent isolated storage. These applications have most of the same security restrictions as traditional web apps and so can be trusted without security warnings or prompts, minimizing user interruptions.
  • Smooth installation. Because Silverlight applications are stored in a local cache and do not require extra privileges to run, the installation process is quick and efficient.
  • Auto-update. Upon launch, Silverlight applications can check for new versions on the server, and automatically update if one is found.
  • Internet connectivity detection. Silverlight applications can now detect whether they have Internet connectivity and can react intelligently including caching a users’ data until their connection is restored.

Views: 1245

Tags:

Silverlight

Error: ServiceHost only supports class service Types

by Viper 17. March 2009 11:53

While adding service reference to a IIS hosted WCF service in Silverlight application, I ran into the following error.

ServiceHost only supports class service Types

In your WCF service if you look at markup .svc file of your service, you will notice from where reference to ServiceHost came. In my service, it looks like as below.


<%@ ServiceHost Language="C#" Debug="true" 
Service="SearchService.SearchServer" CodeBehind="SearchServer.svc.cs" %>

You can see that there are only 2 things that can go wrong in this declaration. One, the service class that implements your service does not match with the declaration in this mark up. This is usually the cause of this error because most of the time you modify the wizard generated interface and service class names and you forget to modify the declarations in this SVC file. Make sure that all entries in mark up file match with actual class and interface names.

Views: 1939

Tags: ,

Silverlight | WCF

Custom tool warning: No endpoints compatible with Silverlight 2 were found

by Viper 10. March 2009 18:40

When you use Add Service Reference wizard to add a reference to existing WCF service to your silverlight application, you may run into this warning. The description of the warning has all the details about the issue and also tells you what to do to fix it. Now you are wondering why this happened. When you use Visual Studio to create WCF project, you will notice that it generates a configuration file for your service as well where you can configure endpoint, bindings etc. for your WCF service. If you have not modified your configuration file, you may notice something like below set as endpoint.

<endpoint address="" binding="wsHttpBinding" 
contract="ByteBlocks.ForExService.ICurrencyService">

Notice that binding is set to wsHttpBinding. This is the binding that provides you connectivity over HTTP/HTTPS with features like reliability, security etc. as specified in WS* protocol. The problem is that Silverlight 2 applications can only connect with ASMX-based web services or services that conform to WS-I Basic Profile 1.1. What that means is that Silverlight applications can only create BasicHttpbinding. So if you modify your service to expose an endpoint that implements basicHttpBinding you are good to go. If your existing WCF service is not tightly coupled with any of WS* features then you can change the existing configuration file as below.

<endpoint address="" binding="basicHttpBinding" 
contract="ByteBlocks.ForExService.ICurrencyService">

Now if you try Add Service Reference tool to add reference to your WCF service, you will not see such warning and a nice set of proxy classes will be created for you to start communicating with WCF service.

Views: 4286

Tags: ,

Silverlight | WCF

System.IO.IsolatedStorage.IsolatedStorageException: Operation not permitted on IsolatedStorageFileStream

by Viper 5. March 2009 19:28

While working on a Silverlight project, I had to write and read some data into Isolated storage. While creating a file in a sun folder i kept getting following error.


{System.IO.IsolatedStorage.IsolatedStorageException: 
    Operation not permitted on IsolatedStorageFileStream.
   at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor
(String path, FileMode mode, FileAccess access, FileShare share, 
Int32 bufferSize, IsolatedStorageFile isf)
   at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor
(String path, FileMode mode, FileAccess access, IsolatedStorageFile isf)
   at System.IO.IsolatedStorage.IsolatedStorageFile.OpenFile
(String path, FileMode mode, FileAccess access)
   at SilverSockets.Page.CreateIsolatedStorageForUser()}

I am developing on Windows7 development machine. So for a moment I thought it may be that there is restriction on Windows7 and I have to make some changes in some silverlight settings or configuration. After spending a few minutes I realized that my creation of sub folder failed in previous step and i did not check it. And I went to on to creating the file in sub folder. Well, the message did not even come close to telling me that folder does not exist. After I fixed creation of sub folder everything worked smoothly. So if you do get this error, check if the folder or file path exists before you go down some wild chase on this error message.

Views: 1636

Tags: ,

.Net | Silverlight

Powered by BlogEngine.NET 1.4.6.1
Theme by Naveen Kohli

Recent

By Categories