Showing posts with label Tips. Show all posts
Showing posts with label Tips. Show all posts

Thursday, September 9, 2010

Bet You Didn't Know

Well ... Of course you know some of them ... Here are they ...

1. When you install Silverlight toolkit, a sample page gets into your machine: You can open the page and have a quick look at the controls. Default location is ...
C:\Program Files\Microsoft SDKs\Silverlight\v4.0\Toolkit\Apr10\Samples\default.htm
You also get the toolkit document in
C:\Program Files\Microsoft SDKs\Silverlight\v4.0\Toolkit\Apr10

2. My domain hosting company doesn't support .xap MIME type: The solution is to change your .xap extension to .zip and it will work. Don't forget to change this in the Object tag source param also. One tiny problem with this approach is that your Splash screen (That you built using plain old XAML and JavaScript) won't work.

3. MouseLeftButtonDown event is not fired when there is no background specified: When you write an mouse event in a Panel you need to specify some background. So if you want to make the background transparent add Background="Transparent" instead of leaving it blank. This is true for other FrameworkElements too (Like Fill in Rectangle)

4. You can specify your custom xml namespaces with default url: You need to add XmlnsDefinitionAttribute in AssemblyInfo.cs file and give an unique url as xml namespace. For example [assembly:XmlnsDefinition("http://mrgni.com","TestLibrary")]

5. You can go full-screen automatically: Well only for Out of Browser applications with elevated trusts. And guess what? All keyboard controls work there.

6. There is no cross domain restriction when your application runs in elevated trust: Well isn't it nice? For elevated trust you can work with COM components. Specially helpful for working with Microsoft Office documents. But whatever you do You can not go Administrator mode in elevated trust mode.




Wednesday, June 24, 2009

Silverlight and LINQ

I got a thread in Silverlight forum that asks how to select a row in a DataGrid?

Now here is the ans using a simple LINQ query.

MyClass item = MyDataGrid.ItemsSource.Cast().Where((_, pos) => pos == row_number).SingleOrDefault();

Now we have the data grid named MyDataGrid and we have already populated it with a collection of MyClass. We are using extension methods of C# 3.0 to help us select a row where row number is known.

In the lambda expression

(_, pos) => pos == row_number

we do not care about the first parameter so I have replaced it with '_'. (Remember '_' is a valid C# identifier).

LINQ has a great power to make your code compact and less error prone. Still I see many people using lengthy (Wrong?) way of doing simple things like selecting from a list where the list value satisfy a certain condition. Many people still things LINQ as an Syntactic Sugar of SQL queries. You can obviously use LINQ to SQL for interacting with database but LINQ is not only that.

LINQ comes in handy while parsing XML too.

Other benefits are like Sorting, advance selection and searching.

Friday, February 6, 2009

Some Guidelines For Developing Silverlight Applications

Hi,
Here are some basic guidelines for building Silverlight applications. They are based on the problems I have faced and seen. Keep in mind none of them are rules, and you can (you should actually) follow only some of them as it suits.

1. Use source control :

Use source control even if you are solo developer.

2. Plan all user controls as early as possible:

Plan your modules early. This will help you plan how to do interaction between them early and you don't have to do some ad-hock fix later. Create them and have some basic methods like Initialize and Deinitialize inside them.(see point 5)

3. Separate each part into a user control:

a. It will help many people working in the same application without much side effect on another control.
b. It helps isolate any problem to a small region so that it would become easy to rectify it.
c. It helps reuse the same control in different places.

Add some classes for basic functionality like checking for URL format or parsing an xml. You can make separate library if they are big enough.

4. Loaded event is harmful:

Do not rely on the loaded events. Why? In one application I was adding and removing an user control when needed, dynamically from code. Each time I was not creating a new object. Instead I was reusing the same one. Now I have attached the MouseLeftButtonDown event inside the loaded event of that user control. What was happening is this. Each time I was adding the user control the loaded event was getting fired and the event was been attached again. So the event handlers are fired multiple times. So adding and removing the user control a few times was making the application run very slow. It took me a hell lot of time to find out why.

So where to put the event handlers? See below.

5. Initialize and Deinitialize :
Put one Initialize and one Deinitialize public method in every user control you make. It is useful in many ways.

a. You can add the event handlers and other code that must run only once inside Initialize
method.

b. You can pass parameters to Initialize method without disturbing the constructor signature
or adding a new constructor. So new YourUserControl ( ) will always work.

c. You can use Deinitialize method to clean up the control. This is specifically required when
you are showing some customized content to the user and need to change it when user
signs out or another user signs in.

Now while creating the user control for the first time you should call the Initialize method with proper parameters.

One disadvantage of this approach is it has the feeling of evil destructors in c++. You need to be careful while calling these two methods.

6. Don't put your event handlers from xaml:

While is perfectly legal to add event handlers from xaml it is better to do it from code. Reason is...

a. Xaml belongs to designers. Event handling belongs to programmers. So its easy to attach
or detach event handlers from code without disturbing the xaml.

b. Suppose you have attached event handler to a control from code. Now if the name of the
control is changed or the control is been removed from xaml you will get an compilation
error with clear meaning. Now if you have written the event handler from xaml and
removed the appropriate method from code you will get an exception with less clear
message.

7. Select your layout carefully:
Take time to select proper layout. I can assure you it will save a lot of your time debugging later. Take your design mock up and think about how you can make the layout. Understand advantages and limitations of Grid, StackPanel, Canvas, Border, Popup, ScrollViewer etc. Some tips for choosing layout.

a. Most of the time you will find Grid is suitable for the top level container (root). This is specially true if your Silverlight application is occupied total page. You will find it containing header, footer and sometimes left and right module. These can be easily done with dividing main root grid with columns and rows.

b. For very complex structures inside the application you will find Canvas is best fitted. Specially if its height width is specified and has overlapped controls inside it.

c. While you are dividing your grid with rows and columns sometimes you will find you need only columns or only rows. Its time for choosing a StackPanel with proper orientation specified. StackPanel also adjust its children while new child is added or removed.

Though its personal preference I prefer to do the top level layout from Visual Studio or at least check the xaml structure in visual studio after making it in blend. It helps prevent some properties getting set automatically without your knowledge and to remove redundant code.

8. Avoid specifying height and width explicitly:

Make your application layout such a way you don't have to specify height and width for each control. Grid has many flexible features like Horizontal and Vertical Alignments, Row and Column properties. Use them wisely. If you make your layout structure carefully you will find most of the time you can avoid using height, width and margin. Also try to avoid negative values in margin. Most of the time it means you have chosen wrong horizontal alignment or vertical alignment property.

9. Don't put any secret inside your code:

Silverlight is a client side technology. Keep in mind all your code goes into users machine and can be easily decompiled to view the code. So never put any sensitive data inside code. Security is the most critical part in today's internet. Security is invisible as long it protects you but it is needed most. Think carefully and from the design phase of your application about security. Don't rely on security through obscurity.

10. Test individual user control:

After creating a user control run it directly from app.xaml.cs by setting the root visual to the control. Call initialize method with proper arguments and check if it works as expected. Test the application thoroughly and fix the slightest defect you found.

11. Don't use image as a button:

In Silverlight 1.0 we did not have any button control so we used some xaml or image for button.
In Silverlight 2 use a button and style it appropriately. It helps in the following way...

a. Maintaining states like mouse over or pressed.
b. Basic functionality like click. (No, click is not same as MouseLeftButtonDown event)
c. Use the same style without copying whole xaml.

This is also valid for all other controls.


12. Don't put redundant code:


Your code should look beautiful. Remove redundant code and simplify the logic as fer as possible. Auto generated codes sometimes generates lot of extra code if you use them in a wrong way. Clean them up.

13. Performance:

a. Reduce your xap size.
b. Reduce the loading time for total or different parts of your application.
c. Avoid windowless=true.
d. Crate vector graphics for simple images.

14. Use web services for server communication:

Silverlight runs on users machine so can not interect with server or database directly. There are many ways of doing it but the best and easiest way is using web services.
Use WCF services if possible.

15. Use Isolated Storage, but carefully:

Use Isolated storage. But DO NOT put any sensitive data there.

Saturday, January 3, 2009

Some More Tips

Here are some Tips.....

1. Reducing xap size
  • Select Release in properties before moving the xap to the production and build.
  • rename the .xap file to .zip. Extract the zip and then re-zip it. It generally decreases the size quite a bit.
  • Use vector graphics instead of images.
  • Load the assets on demand instead of packaging them in the xap.
2. How to set some value to Auto?
  • You can set a value (Say Width of a canvas) to Auto in xaml. How can you do it from code? Set canvas width = double.NaN.
3. ObservableCollection
  • You get a new type of collection with Silverlight, called ObservableCollection. You can use this type of collection wherever you normally use a list. Like setting the ItemsSource of a ListBox. The benefit of using this over List is that it automatically updates the Items whenever the collection changes. This is really helpful for data binding.
4. How to rotate something from its edge?
  • Suppose you have a red rectangle. Now if you rotate it with a storyboard it will rotate like the below image. i.e from center of the rectangle.

Now you want to rotate it from its edge. You can see a small dot in the center of the rectangle like the following in blend design view when you select the rectangle.


That dot defines render transform origin or the origin of all the transformation that will be applied to the rectangle. Now you can drag the small dot to the edge of the stick and the stick (rectangle) will rotate from the edge like the below image.

5. How to set style from code?
  • You can apply a style in xaml like the following. Style="{StaticResource ButtonStyleKeyName}". Now if you want to set it from code do like the following. MyButton.Style = (Style)Resources["ButtonStyleKeyName"];
  • Remember you can set style only once. So if you are trying to do like MyButton.Style = (Style)Resources["ButtonStyleKeyName2"]; After setting the style for the first time you will get an exception.
6. Auto refresh page after silverlight installation.
  • Suppose someone viewing your website and does not have silverlight installed. You prompt him to download and install it. Now after installing the silverlight the page should be auto refreshed so he can see your silverlight application. If you use object tag and include Silverlight.js file this behavior is default. This line in Silverlight.js determines that. Silverlight.onSilverlightInstalled = function () {window.location.reload(false);}; Set the parameter to true if you want to bypass the cache.
  • Could not find a way of doing this with asp:Silverlight tag still. Please tell me if you know the way.
7. Double click support:
8. Where are the dlls for Silverlight?
  • The library dlls for Silverlight are in library folder inside Silverlight SDK. The default location for it is C:\Program Files\Microsoft SDKs\Silverlight\v2.0\Libraries. This is specially useful if you are adding any reference from Expression Blend.
9. How to make sure user does not get the old xap from the browser cache?
  • There are many solution for this. One quick way is to Add a random number in the querystring of the xap source. for ie Source="~/ClientBin/RotateExp.xap?rnd=029db68e-02c0-4dc8-a4f9-81b09f8000da"

That's it for now. Happy New year. :)

Thursday, September 18, 2008

Let's Not Stop Here

[ Updated for Silverlight 2 ]

Hi friends,

In my previous post I have listed 10 lesser known things in Silverlight. Here are some more.....

1. Scale Mode: See the following code.

<div style="height:5;width:500;border:solid 3px #00FF00;"">
<asp:Silverlight ScaleMode="None" Width="100%" Height="100%" ...... />
</div>

Now see the blue part. There are 3 values you can set in ScaleMode. None (that is default), Stretch and Zoom.

None: The Silverlight component retains its size specified inside. (in Page.xaml for example)
Stretch: The Silverlight component occupies the available space inside the div.
Zoom: Like Stretch but keeps the aspect ratio.

Now we have one Silverlight application. In the Page.xaml we have set the height and width of the user control to 100 and 400. We have one grid that occupies this usercontrol and has a red background.

Now in the html we have set silverlight contenainer div size to be 500 x 500. If we now set ScaleMode="None" That is default we will see our application rendered like the following.



The green border is the border of the silverlight container div. Red part is our original silverlight component.

Following is in Stretch mode



This is in Zoom mode



See how it preserves its aspect ratio in Zoom mode.


2. Check Silverlight Version: You can check what silverlight version is installed in your computer in this page.

3. Silverlight Event Bubbling: Silverlight has some events that are called routed events and they bubble from child to its parent element. Mainly mouse and keyboard events fall in this category.

This simple application will show how Silverlight event bubbling works and what you can do to allow or stop it.

Lets have 3 canvases and arranged them like the following

Blue Part is the root canvas, red one is a child inside blue one and green one is inside red canvas.

RootCanvas -> Blue one
Child1Canvas -> Red one
Child2Canvas -> Green one

Now we will write 3 MouseLeftButtonDown event handlers for 3 of them.

public Page()
{
InitializeComponent();
Loaded += new RoutedEventHandler(Page_Loaded);
}

void Page_Loaded(object sender, RoutedEventArgs e)
{
RootCanvas.MouseLeftButtonDown += new MouseButtonEventHandler(RootCanvas_MouseLeftButtonDown);

Child1Canvas.MouseLeftButtonDown += new
MouseButtonEventHandler(Child1Canvas_MouseLeftButtonDown);

Child2Canvas.MouseLeftButtonDown += new
MouseButtonEventHandler(Child2Canvas_MouseLeftButtonDown);
}

void Child2Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
}

void Child1Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
}

void RootCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
}


Now set breakpoints on each of the event handlers to see what is going on. You can also put alert for it. Now run the application and click on the green canvas. You will see the break points are hit in the order green canvas (child 2) to its parent red canvas to its parent the blue canvas.
Now this is the default behavior. Now suppose we want to pass the event from green to its parent red but not to the blue one. Now as at the red canvas we want to stop the bubbling we have to write
e.Handled=true at its event handler. Now the event will not be passed to the blue one.

void Child1Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
}

Now Silverlight controls handles the mouse events internally and they don't let them bubble. So if you place a button or other Silverlight control inside the green canvas you will not be able to catch its mouse down event or pass it to the parent canvas.

See this great blog post and this documentation for details.


4. Enable help for Silverlight in Visual Studio 2008: You already installed Silverlight SDK and still can't see help on Silverlight from Visual Studio? Here is how to enable it.

1. Open Visual Studio (you might have to open VS as an administrator).
2. In the Help menu, choose Index. Microsoft Document Explorer displays.
3. In the Filtered by: drop-down, choose to (unfiltered).
4. In the Look for field, type Collection Manager.
5. Below the Collection Manager heading, double click Help.
6. Below the Collections available for inclusion in VSCC heading, check Microsoft Silverlight 2
SDK Documentation.
7. Click Update VSCC.

Now after restarting visual studio you can see it in help -> contents.

This steps you can find inside the readme file
C:\Program Files\Microsoft SDKs\Silverlight\v2.0\Documentation\VS-Help\en-us\readme.txt

5. Document outline: This is actually a feature in visual studio. If you layout is complex and you want to easily navigate to parent or child elements you can use this. View -> Other winndows -> Document outline.

6. Why my mouse events aint working? Have one simple Silverlight application with a green Grid with height and width 300 and 400. At the MouseLeftButtonDown event handler write one alert.

private void LayoutRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
HtmlPage.Window.Alert("Event is Fired and catched");

}

Now run the application and click the Grid. The alert will come. Now remove the background attribute from the grid and run the application. Click the grid. No alert will come. :). Though I don't know the reason for it but it might be intentional. Guess why? It might prevent bad guys to fool user think clicking an html element.

Thanks all for keep on visiting my blog. I am a bit busy with my work right now and I will post some material for the newbies in Silverlight in my future posts.

Tuesday, July 29, 2008

Some Lesser known things in Silverlight

[ Updated for Silverlight 2]

Here are some of them.......


1. EnableFrameRateCounter :
Wander what fps (Frames per Second) is you silverlight application running? Set EnableFrameRateCounter="true" in your aspx page.
The default maximum value is 60

this is what is shows in my browser. 19.74 is actual and 60 is max set value.




You can set MaxFrameRate there in that tag too. The Actual fps will depend with processor speed and how busy it is.


2. EnableRedrawRegions:
This is sometimes helpful when debugging. Setting it true will show when Silverlight redraws any region. Here I what I got when animating a circle.




3. PluginNotInstalledTemplate: This is useful when you want to do something when Silverlight plugin is not installed in users browser. This is how to do it

<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/TicTacToe.xap" MinimumVersion="2.0.30523"
Width="100%" Height="100%">
<PluginNotInstalledTemplate>
Write something to show if plugin not installed
</PluginNotInstalledTemplate>
</asp:Silverlight>

4. SplashScreen: Whenever we start a silverlight application the silverlight control provides a default splash screen while the xap file is loading. It is pretty good but still sometimes we need to add our own splash screen. Here is the Silverlight tutorial that shows it step by step.

Here is a blog post that will help providing splash screen with asp:Silverlight tag.


5. InitParameters: You can pass initialization variables with InitParameters. here is a sample

InitParameters="BaseUrl=http://live.com,ResourceUrl=http://www.microsoft.com">

and now from App.Xaml.cs file

private void Application_Startup(object sender, StartupEventArgs e)
{
string baseUrl = e.InitParams["BaseUrl"];
string reasourceUrl = e.InitParams["ResourceUrl"];
this.RootVisual = new Page();

}
You can pass the parameters in the constructor of Page class.

6. Read Query Strings: Add System.Windows.Browser namespace where you want to access query string.

if(HtmlPage.Document.QueryString.Keys.Contains("Name"))
{
string name = HtmlPage.Document.QueryString["Name"];
}

Url- http://SampleDomain/SamplePage.aspx?Name=Tanmoy

7. Famous Firefox nested DIV problem: Strictly speaking this is not related to silverlight. Still you might have faced this problem with firefox. Try to run the following in FF.

<div>
<div style="height: 100%;">
<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/TicTacToe.xap" MinimumVersion="2.0.30523"
Width="100%" Height="100%">
<PluginNotInstalledTemplate>
Write something to show if plugin not installed
</PluginNotInstalledTemplate>
</asp:Silverlight>
</div>
</div>


It will run in IE but not in FF. Remove the upper DIV and it will run properly. One work around is to set height=100% to the upper DIV. This problem is because FF deals DIV differently.

8. What the ifame is doing here?: If you see the html object code for silverlight page you will see one iframe after the object tag.
<iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>

The reason behind this iframe is stated in the documentation like the following

The presence of an IFrame prevents the Safari browser from caching the page. Safari caching prevents the Silverlight plug-in from reloading when the user navigates back to a previously-visited Silverlight page.

9. How to open .xap file: I guess you already know it but if you don't it is one coolest thing. XAP is a binary format but it is actually a .zip file renamed to .xap. So you can open it with WinZip or any other .zip file opener. It has one AppManifest.xaml file inside that defines the entry points and other assembly you are using. It also will have DLLs and optionally any resources you need to be loaded with the xap.

10. Relative positioning: It is possible to position the elements inside the Silverlight component relatively. For this you have to use Grid or StackPanel. I am showing it with a code.

<Grid x:Name="LayoutRoot" Background="Gray" ShowGridLines="True" HorizontalAlignment="Center" VerticalAlignment="Center" Width="300" Height="300">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions >
<RowDefinition Height="50" />
<RowDefinition Height="2*"/>
<RowDefinition Height="auto" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle Grid.Column="2" Grid.Row="2" Height="40" Width="30" Fill="Blue" />
</Grid>

First the ShowGridLines="True". It is very useful when you are experimenting with Grids. It shows the outlines of your Grid with dotted lines.

Now here is the output I got


Now here is explanation.

Total width is 300 px and it is distributed with 4 columns in 1:2:3:1 ratio.

Now coming back to rows. There are 4 rows sharing 300px height. But one of them is occupying 50px. Now the height of the 3rd row is set to auto. That means it will take the height of its child element. That is the blue rectangle. Rest of the height available will be distributed with other two rows with 2:1 ratio.

I have been writing this post for quite a long time. Been busy with other tasks too. In anything you want to ask please leave a comment.