Some people ofter forget about this (even me ) So that;’s why I’m posting about this.
In my work (at Artinsoft) we are currently performing a lot of Winforms and VB6
migration to Silverlight. And a common problem is “What can I do with the user settings!!!”.
In VB6 you had your INI files and in Winforms you probably used something like the App settings.
But when you move to Silverlight what can you do!.
You need a set of initial values and you probably wont want to “burn” those inicial values in your XAP file.
It would be nicer if those values can just be set in the Web.Config file.
So a common way to solve this, is develop a simple helper class. This helper class will use a service that will
collect your initial ini files or appsettings values and store them in your Isolated Storage.
You can even use some kind of basic cryptography if you feel that your date is sensitive.
And then you can use the helpful IsolatedStorageSettings class. For example see this code,
that I borrowed from this post: http://wildermuth.com/2008/10/21/Using_Isolated_Storage_Settings_in_Silverlight_2
const string FAVCOLORNAME = "favoriteColor";
public Color? FavoriteColor
{
get
{
if (IsolatedStorageSettings.ApplicationSettings[FAVCOLORNAME] != null)
{
Color? colorSetting = IsolatedStorageSettings.ApplicationSettings[FAVCOLORNAME] as Color?;
if (colorSetting != null) return colorSetting;
}
// If we can't find a favorite color, return a null color
return new Color?();
}
set
{
IsolatedStorageSettings.ApplicationSettings[FAVCOLORNAME] = value;
}
}
As you can see is very easy to save and recover simple settings from the Silverlight Isolated Storage
Specially if you are working with Silverlight and Azure you will end up in situation where you would
like to redirect your WCF Endpoint dinamically ( I don’t think you can guess the GUID that Azure will generate
for your staging enviroment).
Out of the box the silverlight behaviour is that the WCF endpoints are hardcoded in a config file called
ServicesClient.config embedded in the .xap file.
This can be problematic at least for Azure deployment infraestructure because you can deploy to different sites:
Staging and Production.
Each of this Web Sites will have differente URLs.For example phonebook.cloudapp.net or asdf-asdf-asdf-dasxxx.cloudapp.net
So an easy workaround is:
In WCF when a channel is created in code you can specify the endpoint,
so we only need to created different endpoints depending of the site where the the .xap file was download.
The proposed changes will be:
For example if you create services in your App.xaml.cs method Application_Startup
Then you can change your code for something like:
string url = "http://" + HtmlPage.Document.DocumentUri.Host + "/MyService.svc";
EndpointAddress endpoint = new EndpointAddress(url);
var service = new MyService(new ChannelFactory<IMyService>("*").CreateChannel(endpoint)));
This will allow you to just deploy your application to either Staging or Production environment
in Azure with no more code or config file changes.
While developing some user controls in Silverlight I have come with a situation,
for example when dragging a Chart control in the Visual Studio 2010 designer where I get something like:
Error HRESULT E_FAIL has been returned from a call to a COM component
I have been looking for a solution but have not found anything yet.
The only workaround has been:
a) Close all windows. Do a Clean and a Rebuild or Close Visual Studio and open it again.
Today I found this excellent post:
http://smehrozalam.wordpress.com/2009/01/29/retrieving-huge-amount-of-data-from-wcf-service-in-silverlight-application/
and I was the key to solve a problem I had with a WCF service.
I had made some changes to an application to send a text file to the server
for batch processing, everything was working fine until I started sending big files.
I just received one of those obnoxious Not Found error.
So what could I do? Well as any respectable WCF developer would I started tracing the WCF messages with Fiddler, and I found this:
If you cannot read it from the image the message was:
DeserializationFailed… The formatter threw an exception while trying to deserialize the message:
There was an error while trying to deserialize parameter :_xxxxxx.
The InnerException message was 'There was an error deserializing the object of type System.String.
The maximum string content length quota (8192) has been exceeded while reading XML data.
This quota may be increased by changing the MaxStringContentLength property on the XmlDictionaryReaderQuotas
object used when creating the XML reader.
I was a little confused but thanks to that post I was able to just add:
<binaryMessageEncoding maxWritePoolSize="16" maxSessionSize="8192">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binaryMessageEncoding>
And got everything working again!
If for any reason you have to debug and develop Silverlight VS 2008,
and you encounter a problem that when you start debugger it reports
something as if the version you have is not supported then first do this:
Open regedit and check:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Silverlight\Components\Debugging\Value
A Version value of 4.0.50917.0 means that you have the Silverlight 4 Developer and you need to:
1. erase this entry.
2. Uninstall Silverlight 4 Tool
3. Reinstall Silverlight 3 Tools for Visual Studio 2008.
VB6 and WinForms ListBox has the built in capability to provide a simple data look up. But the Silverlight ListBox does not.
So if you have a list with items:
Apple
Airplane
Blueberry
Bee
Car
Zoo
Animal Planet
And your current item is Apple when you press A the next current item will be Airplane
Apple
Airplane
Blueberry
Bee
Car
Zoo
Animal Planet
And the next time you press A the next current item will be Animal Planet
Apple
Airplane
Blueberry
Bee
Car
Zoo
Animal Planet
And the next time you press A the next current item will be Apple again
Ok to do in Silverlight you need to add a event handler. You can create a user control and this event handler and replace your listbox for your custom listbox or just add this event handler for the listboxes that need it. The code you need is the following:
void listbox1_KeyDown(object sender, KeyEventArgs e)
{
String selectedText = this.listbox1.SelectedItem.ToString();
String keyAsString = e.Key.ToString();
int maxItems = listbox1.Items.Count;
if (!String.IsNullOrEmpty(selectedText) &&
!String.IsNullOrEmpty(keyAsString) && keyAsString.Length == 1 &&
maxItems > 1)
{
int currentIndex = this.listbox1.SelectedIndex;
int nextIndex = (currentIndex + 1) % maxItems;
while (currentIndex != nextIndex)
{
if (this.listbox1.Items[nextIndex].ToString().ToUpper().StartsWith(keyAsString))
{
this.listbox1.SelectedIndex = nextIndex;
return;
}
nextIndex = (nextIndex + 1) % maxItems;
}
//NOTE: theres is a slight different behaviour because for example in
//winforms if your only had an item that started with A and press A the selectionIndex
//will not change but a SelectedIndexChanged event (equivalent to SelectionChanged in Silverlight)
//and this is not the Silverlight behaviour
}
}
During a Silverlight migration project from VB6 I was trying to add a WCF reference,
everything seemed to work in the wizard but no code was generated.
After reviewing the Warning messages, i found that some said:
Custom tool warning: Cannot import wsdl:portType
What I did to solve this issue?
1. Right click on your service reference
2. Select Configure Service reference
3. Uncheck the option that says Reuse types in referenced assemblies.
4. Press OK
After that VS generated the code and I could use the WCF service.
I have a silverlight application that I was trying to publish from Visual Studio to my local IIS and I got this problem:
For the record I have Windows 7.
So you can write on the Search program and Files “ Turn Windows Features on or off”
And then select
If you are doing Silverlight development, one thing that can be cumbersome is keeping in sync
your development and production settings. Specially if you are using WCF services because you have
to make sure that your ServiceClient.config file has the right values.
What I usually do is this.
1. First set fixed ports for my application. See http://blogs.msdn.com/b/webdevelopertips/archive/2008/11/07/tip-21-did-you-know-how-to-set-a-fixed-port-for-the-developer-web-server.aspx
2. Modify my hosts file in C:\Windows\System32\drivers\etc adding an entry like:
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host
# localhost name resolution is handled within DNS itself.
127.0.0.1 localhost
127.0.0.1 productionserver.cloudapp.net
In this way all you have to change is your hosts file and you keep the same settings for development and for production
One obvious thing in modern symbian mobiles, is how to detect orientation.
I am currently porting some Silverlight 1.0 samples like GrandPiano to Silverlight for Symbian and I was wondering
how can I detect the phone orientation. Well I just analysed the Bing demo and find out that is kind of simple.
What you need is something like this:
public static readonly DependencyProperty OrientationProperty =
DependencyProperty.Register("Orientation", typeof(Orientation), typeof(Page),
new PropertyMetadata((Orientation)0, new PropertyChangedCallback(OrientationPropertyChanged)));
private static void OrientationPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
(sender as GrandPiano).UpdateOrientation();
}
private void UpdateOrientation()
{
base.Width = (this.Orientation == Orientation.Vertical) ? DeviceVerticalSize.Width : DeviceVerticalSize.Height;
base.Height = (this.Orientation == Orientation.Vertical) ? DeviceVerticalSize.Height : DeviceVerticalSize.Width;
base.Clip = new RectangleGeometry { Rect = new Rect(new Point(), new Size(base.Width, base.Height)) };
}
// Properties
public Orientation Orientation
{
get
{
return (Orientation)base.GetValue(OrientationProperty);
}
set
{
base.SetValue(OrientationProperty, value);
}
}