Wednesday, January 27, 2010

Silverlight 3: Auto select text in TextBox

Missing out of the box in Silverlight 3 is the ability to auto select the text in a textbox when it receives focus. Thankfully Attached Properties make it very easy to add the functionality. In this post I will create a AutoSelectText attached property, which when set to true will select all the text as when the textbox receives focus. And because of routed events, it is not required to add the property to every textbox on a page. Instead it can be added to the parent content control and all child textboxes will have to auto select behavior.

Usage

  1. <Grid x:Name="LayoutRoot"
  2.     attachedProperties:AttachedProperties.AutoSelectText="true">
  3.     <StackPanel Orientation="Vertical"
  4.                 HorizontalAlignment="Left">
  5.                  <TextBox Text="Will not auto select"
  6.                  MaxWidth="300"
  7.                  Margin="4"
  8.                  attachedProperties:AttachedProperties.PreventAutoSelectText="true" />
  9.         <TextBox Text="Will auto select 1"
  10.                  MaxWidth="300"
  11.                  Margin="4"/>
  12.         <TextBox Text="Will auto select 2"
  13.                  MaxWidth="300"
  14.                  Margin="4" />
  15.     </StackPanel>
  16. </Grid>

Line 2: The AutoSelectText is set to true on the root level content control (Grid). That’s it. All text boxes within the Grid will participate in the auto select text functionality.
Line 8: A control can opt out by setting the PreventAutoSelectText property to false.

Listed below are some of the key code blocks. The link to the entire source code can be found at the end of the post.

Declaring the attached property

  1. public static readonly DependencyProperty AutoSelectTextProperty = DependencyProperty.RegisterAttached("AutoSelectText",
  2.                                                                        typeof(Boolean),
  3.                                                                        typeof(AttachedProperties),
  4.                                                                        new PropertyMetadata(OnAutoSelectTextChanged));
  5.  
  6. public static readonly DependencyProperty PreventAutoSelectTextProperty = DependencyProperty.RegisterAttached("PreventAutoSelectText",
  7.                                                                               typeof(Boolean),
  8.                                                                               typeof(AttachedProperties),
  9.                                                                               null);

Line 1-2: A new boolean attached property called AutoSelectText is declared.
Line 4: The OnAutoSelectTextChanged event handler is registered, which is be invoked when the value of the property is set in the xaml.
Line 6: A new boolean attached property called PreventAutoSelectText is declared. Controls can use this property to opt out of the auto select functionality.

The dependency property changed event handler

  1. private static void OnAutoSelectTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  2. {
  3.     //This works because of event bubbling.
  4.     FrameworkElement frameworkElement = d as FrameworkElement;
  5.     if (frameworkElement != null)
  6.     {
  7.         if ((bool)e.NewValue)
  8.             frameworkElement.GotFocus += OnGotFocus;
  9.         else
  10.             frameworkElement.GotFocus -= OnGotFocus;
  11.     }
  12. }

Line 8: If the value of the AutoSelectText (accessed using e.NewValue) is true, we add the OnGotFocus event handler to the GotFocus event of the control on which the AutoSelectText property is being set (from the xaml).
Line 9: Similarly if the control does not wish to participate in auto selecting of text, we remove our event handler.

The GotFocus event handler

  1. private static void OnGotFocus(object sender, RoutedEventArgs e)
  2. {
  3.     TextBox textBox = FocusManager.GetFocusedElement() as TextBox;
  4.     if (textBox != null && !(bool)textBox.GetValue(PreventAutoSelectTextProperty))
  5.         textBox.Select(0, textBox.Text.Length);
  6. }

Line 3: Since we are using routed events, the sender parameter will not be the textbox that currently has focus. It will the root level content control (Grid) which has the AutoSelectText attached property. The FocusManager class is used to get a reference to that control that has the focus.

Why two attached properties?

Silverlight does not provide a way to check if a control has a attached property defined in the xaml. Due to this if I replace

  1. if (textBox != null && !(bool)textBox.GetValue(PreventAutoSelectTextProperty))

in the OnGotFocus method with

  1. if (textBox != null && !(bool)textBox.GetValue(AutoSelectTextProperty))

I will always get false for the textBox.GetValue call, even if the AutoSelectText has not been defined for the textbox in xaml.

Download source code for AutoSelectText attached property.

Friday, October 16, 2009

RIA Services Change Set Conflict Resolution using ResolveChangeSet

If there are optimistic concurrency errors when a change set is submitted to a RIA Services DomainService, the error information is reported to the client in the resulting SubmitOperation via the Entity.Conflict member. Server side conflict resolution can be added by adding entity specific resolve methods in the DomainService. For example to handle optimistic concurrency errors for the Product entity you can add a ResolveProduct method in the DomainService.

   1: public bool ResolveProduct(Product currentProduct, Product originalProduct,
   2:     Product storeProduct, bool deleteOperation)
   3: {
   4:     return base.Resolve(currentProduct, originalProduct, storeProduct,
   5:                         ResolveOption.KeepChanges);
   6: }

The code snippet listed above is from the Microsoft .NET RIA Service Overview (July 2009 Preview) document.

Global Conflict Resolution


With this method, a separate resolve method is required for each entity, which is not scalable if there happen to be a large number of entities the domain. In such a case we need another way of handling conflict resolution. Global conflict resolution can be implemented by overriding the ResolveChangeSet method of the DomainService. If you are unaware of ResolveChangeSet method, check the Server Side Change Set Processing section listed after this one.

The ResolveChangeSet method is called for every conflict, regardless of entity type and can be overriden to provide global conflict resolution. Listed below is a code snippet that can be used for last one wins type resolution.



   1: protected override bool ResolveChangeSet(ChangeSet changeSet)
   2: {
   3:     bool resolveChangeSetSuccess = true;
   4:     bool resolveSuccess = false;
   5:  
   6:     foreach (EntityOperation entityOperation in changeSet.EntityOperations)
   7:     {
   8:         resolveSuccess = base.Resolve(entityOperation.Entity, entityOperation.OriginalEntity, 
   9:             entityOperation.StoreEntity, ResolveOption.KeepCurrentValues);
  10:         
  11:         if (resolveSuccess)
  12:             entityOperation.ConflictMembers = null;
  13:  
  14:         resolveChangeSetSuccess = resolveChangeSetSuccess && resolveSuccess;
  15:     }
  16:     if (resolveChangeSetSuccess)
  17:         this.Context.SubmitChanges();
  18:  
  19:     return resolveChangeSetSuccess;
  20: }


Line 8-9: For each entity in the change set, we resolve the conflict by specifying the ResolveOption.KeepCurrentValues (last one wins).
Line 12: One would think that if the method returns true, the error will not be reported to the client. However that is not the case. The ConflictMembers has to be set to null to prevent the conflict error from being reported to the client.

Line 17: If all the entities could be successfully resolved, the change set is saved.

Server Side Change Set Processing


When a change set is submitted to the DomainService, a predefined sequence of methods are called to authorize, validate and persist the change set. This sequence is listed below:

  1. Submit – the service entry point that receives the change set and begins the change set processing pipeline.

  2. AuthorizeChangeSet – Verifies Permission/Authorization for each operation. If any operations are not permitted, processing stops and an error is returned to the client.
  3. ValidateChangeSet – Validation for all operations in the change set is run. If any operations fail validation, processing stops and errors are returned to the client.
  4. ExecuteChangeSet – The corresponding method for each operation in the change set is invoked. This is the point in time when your business logic is run. If any operations failed, processing stops and errors are returned to the client.
  5. PersistChangeSet – At this point all the domain operations have been executed, and this method is called to finalize the changes.
  6. ResolveChangeSet – If there were any optimistic concurrency errors, this method is called to resolve them.

Thursday, September 24, 2009

XAML binding CodeRush templates

When I first started coding in Silverlight, I could never remember the syntax for databinding in XAML. Everytime I had to do databinding I found myself referring to the documentation. The lack of intellisense or compile time syntax checking was no fun either. So after a few days I created a few CodeRush templates, which I still use to speed up development. You can download them at the end of this post. The templates are:

bp (Bind to Property):

bsr (Bind to Static Resource):

bc (Bind using Converter):

  

be (Bind to Element):

Download XAML binding CodeRush templates

Tuesday, September 16, 2008

Couple of XAML Editor enchancements in Visual Studio 2008 SP1

The "Go To Definition" functionality in the XMAL code behind editor has been enhanced in Visual Studio 2008. Invoking it on a reference of a control in the XAML code behind page, now takes the user to the definition of the control in XMAL code. What a pleasant change from the prior behavior where invoking the command would take the user to the designer generated code behind page.

So when you do this:

image 

You get this:

 image

instead of (in the .g.cs file)

image 

The “Find all References” functionality has also been enchanced with the service pack. Invoking it on a reference of a control in the XAML code behind page, now inclues the references made in the XAML code also.

So when you do this:

image

You get this (Note the third reference in the tablecontrol.xaml file):

image

Wednesday, August 13, 2008

Programmatically creating DotNetNuke user passwords

When programmatically creating a DotNetNuke portal, the CreatePortal method API expects passwords that are already encrypted. In DotNetNuke, by default the passwords are encrypted using one way Triple DES algorithm. There is existing functionality in DotNetNuke that can be reused to encrypt plain text passwords. Listed below is some sample code that can be used.

Requirements: The code listed below uses the following classes that can be found in the assembly: DotNetNuke.dll

  • DotNetNuke.Security.PortalSecurity
  • DotNetNuke.Common.Globals
  • DotNetNuke.Entities.Users.UserController

   1: string userName = "sampleUserName";
   2:  
   3: //generate a random 8 character password
   4: string password = UserController.GeneratePassword(8)
   5:  
   6: //get the machine's encryption key
   7: string key = Convert.ToString(Globals.HostSettings["EncryptionKey"]);
   8:  
   9: //encrypt the password with the machines encryption key
  10: PortalSecurity portalSecurity = new PortalSecurity();
  11: password = portalSecurity.Encrypt(key, password);

Line 4: We generate a random 8 character password using the static GeneratePassword in the UserController class. It is not required to use the method, you can substitute it with you own logic. Keep in mind to satisfy the password requirements configured in DotNetNuke.
Line 7: When users login, DotNetNuke encrypts the plain text password using the encryption key that is stored in the web.config. It then compares it to the encrypted version that is stored in the database, and if they match the login successed. We have to use the same encryption key or else the user will not be able to login even if he uses the right password. We use the Globals class which contains a collection of utility functions, to retrieve the encryption key.
Line 11: We use the Encrypt method of the PortalSecurity class to encrypt the password.

Thursday, July 31, 2008

Programmatically checking if the required alias is available in DotNetNuke

If you try to create a portal with a alias that in not available, DotNetNuke will complain about it and not allow you to continue ahead. It turns out that this duplication check is done by the UI and not the business layer. So if you are programmatically creating a portal, you will have check if the required alias is available, because the DotNetNuke API does not do it.

Requirements:
All the classes used below can be found in the assembly: DotNetNuke.dll in the DotNetNuke.Entities.Portals namespace

Listed below is some sample code you can use the following code you programmatically check if the required alias is available in DotNetNuke.

   1: public static bool IsAliasAvailable(string alias)
   2: {
   3:     //need to make sure that the alias does not contain http://
   4:     alias = alias.Replace(@"http://", "");
   5:  
   6:     PortalAliasController aliasContoller = new PortalAliasController();
   7:     PortalAliasCollection aliasCollection = aliasContoller.GetPortalAliases();
   8:     return  !(aliasCollection.Contains(alias));
   9: }


Line 4: Since DotNetNuke does not store the "http://" part of the alias in its database, remove it from the string holding the alias before checking.
Line 7: Use the GetProtalAliases method in PortalAliasController class to get a PortalAliasCollection.
Line 8: Since PortalAliasCollection inherits from System.Collections.DictionaryBase, you can use the Contains method to check if the alias is available.

Tuesday, July 1, 2008

Programmatically creating DotNetNuke portals - Part 1

If the need ever arises you can use C# to use the DotNetNuke API to programmatically create portals you can use the code listed below. Of course the code will need all the right permissions to do this. You will need the following information to create the portal.

  1. Portal Name
  2. Administrator first name and last name
  3. Administrator username and password
  4. Administrator email
  5. Portal description
  6. Portal Keywords
  7. Name (including path) of the template to the applied to the portal
  8. Portal Alias
  9. Server path (the path to the root of the Application)
  10. If it is a child portal the child path (the path to the child portal folder)

Listed below are the required steps to create the portal and perform some essential house keeping activities:

  1. Make sure that the alias does not contain the string "http://".
  2. Check if the required alias is available.
  3. Encrypt the administrator password with the machine encryption key.
  4. Get all the required paths: template path, home directory and server path.
  5. Create the portal.
  6. Add the new http alias (url) to the Http handler.
  7. Log the portal creation event tp DotNetNuke's event log.

In the next few days, I'll add a detailed post for each of the steps listed above.

Update 1: I've just posted an article on Programmatically checking if the required alias is available in DotNetNuke

Update 2: I've just posted an article on Programmatically creating DotNetNuke user passwords

Monday, June 23, 2008

Upgrading DotNetNuke from 4.4.1 to 4.8.4

Upgrading DotNetNuke from one version to another is fairly simple other than the fact that the changes in the web.config file need to be made by hand (although this is not true any more). I recently upgraded my system from 4.4.1 to 4.8.4 and faced a couple of issues that I have listed below.

Before you read any further, I would like to advice you to take a back up of your database and file system. I cannot emphasize enough on how important this is. I had to restore both of them several times in my beta environment during the recent upgrade as I worked through the issues.

Since I was skipping multiple versions, I decided to use the 4.8.4 install version of DotNetNuke.

Problem 1: Installing Package File OpenID_01.00.00_Install: Error

This was the first issue I faced. Because I do not need the provider I could continue ahead. I restored the database and file system. But before re-running the installer I removed the files

  • Install\Package\LiveID_01.00.00_Install.zip
  • Install\Package\OpenID_01.00.00_Install.zip

I have Googled for this error and am unable to find a solution for this problem.

Problem 2: Redirect Loop: Firefox has detected that the server is redirecting the request for this address in a way that will never complete

After the installation is complete, I tried to browse to the home page in Internet Explorer. It kept trying to load the page for 5 minutes, but never timed out. So I tried it in Firefox and that's when I got the message. If in your web.config the trust level is set to Medium, change it to Full. That should fix this problem. If you were already at Full trust, compare the code in Default.aspx with the version of the file in the installation package. If they differ, then replace the file on your system with the file from the installation package.

Sunday, June 22, 2008

CodeSmith 5.0 Beta released

If you use the popular code generation tool CodeSmith, you'll want to download the latest beta release. It adds support for .NET 3.5. So now you'll be able to use LINQ in your templates. There are also some code generation performance improvements. Read more about it here.

(Via Rob Howard's blog)

Thursday, June 19, 2008

Anti-virus and search indexing programs can affect Visual Studio build performance

On Scott Guthrie's blog, he has mentioned how sometimes anti-virus and search indexing programs can affect Visual Studio's build performance.

One issue I've seen reported several times are cases where virus scanners, spy-bot detecters, and/or desktop search indexing tools end up monitoring a directory containing a project a little too closely, and continually change the timestamps of these files (they don't alter the contents of the file - but they do change a last touched timestamp that VS also uses).  This then causes a pattern of: you make a change, rebuild, and then in the background the virus/search tool goes in and re-searches/re-checks the file and marks it as altered - which then causes VS to have to re-build it again.

Such programs are known to cause problems on production systems too.

(via: Visual Web Developer Team Blog)

Wednesday, June 18, 2008

Chance to win free .NET eBooks

Manning.com is giving away one free .NET eBook every day starting tomorrow until July 17, 2008. You can sign up for the lucky draw here.

Listed below are links to some of their books on Amazon:

One lucky guy will win the entire catalog of all Manning .NET  eBooks.

Tuesday, June 3, 2008

Sys.WebForms.PageRequestManagerParserErrorException

Recently I inherited a ASP.NET project from a colleague, who left the company. Call it Murphy's law or whatever, but the very first time I tried to make changes I got the following exception at run time: Sys.WebForms.PageRequestManagerParserErrorException. After a little bit of Googling I found out the cause. I was using the UpdatePanel and using a Response.Write in my PageLoad. Eilon Lipton's blog post has more details.

Monday, December 3, 2007

Free ASP.NET Rich Text Editor control

Check out this awesome free rich text editor. The source code can be found at CodePlex at: RTE (Rich Text Editor) ASP.NET Control

The project page lists the following features 

Supported Browsers: Internet Explorer and FireFox
Supported Styles / Formats: Bold, Italic, Underline, Justify, indentations, Plain Lists, Numbered Lists
Supported Commands: Copy, Paste, Cut, Add Hyperlink, Set Foreground Color, Set Highlight Color, Set Fonts, Set Font Sizes, Insert Smiles
Supported Views: Text View, Html View

You can see a demo on this page: http://rteditor.members.winisp.net/

Technorati Tags:

Visual C# 2008 shortcuts

I found a nice PDF file that lists the most frequently used shortcuts in Visual C# 2008. You can download it from the Visual C# 2008 Keybinding Reference Poster page. I haven't had the time to check how many shortcuts differ from those in Visual C# 2005.

If you are using Visual C# 2005 check out this post: Visual C# 2005 shortcuts

Technorati Tags: , , ,

Friday, September 28, 2007

Partial methods

Visual Studio 2008 allows the use of partial methods. Partial methods are nothing but a compiler trick (just like partial classes). Designer generated code can provide hooks into their class methods, by using the partial keyword. Users of the class can then hook into those methods and provide their own implementation. When a partial method has no body then the partial method is not emitted to metadata. So in a sense they are optional methods.

Check out this video on partial methods titled: Partial Methods in C#3 and VB9 by Daniel Moth. In it he explains what partial methods are and their limitations. He also compares them to the Conditional attribute and event handlers.

Technorati Tags: ,

Friday, September 7, 2007

External settings file for ClientSettingsSection (applicationSettings)

Very often we define application settings in application configuration sections and would like to isolate the configuration section into an external settings file. Creating external settings file using the configSource attribute for the predefined configuration sections (AppSettings, ConnectionStrings etc) is well documented. But the literature for custom configuration section is sparse.

Listed below is a sample configuration file that contains a configSource attribute being used in a ClientSettingsSection. I have kept only the essential parts of the file:

   1: <configSections>
   2:   <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup">
   3:     <section name="MyApplication.Properties.Settings" type="System.Configuration.ClientSettingsSection"/>
   4:   </sectionGroup>
   5: </configSections>
   6:  
   7: <applicationSettings>
   8:   <MyApplication.Properties.Settings configSource="BusinessLogic.config" />
   9: </applicationSettings>

Line 8: Using the configSource attributed to define an external settings file called "BusinessLogic.config"


A couple of things of note:
- Unlike how it does for predefined configuration sections, Visual Studio does not provide intellisense when trying to add the configSource attribute to ClientSettingsSection.
- The external settings file has to be in the same directory or subdirectory as the configuration file. So line 8 can be replaced with the following line:


<MyApplication.Properties.Settings configSource="ConfigFiles\BusinessLogic.config" />

Listed below is the "BusinessLogic.config" file


   1: <MyApplication.Properties.Settings>
   2:   <setting name="InitializationVector" serializeAs="String">
   3:     <value>1234567890abc!@#</value>
   4:   </setting>
   5:   <setting name="KeySize" serializeAs="String">
   6:     <value>256</value> 
   7:   </setting>
   8: </MyApplication.Properties.Settings>

 

Technorati Tags: , ,

Thursday, September 6, 2007

Getting line numbers in exception stack trace in a Windows Service

The Exception.ToString() method contains call stack information when the exception was thrown. However if the PDB files from the assemblies involved are available, this information also contains file names and line numbers at each level of the stack trace. Needless to say that this information can be very beneficial to the developer.

The CLR will look for the PDB files in the runtime working directory, which for most applications is the installation directory itself. However for windows services the working directory is the windows systems32 directory (For eg: C:\Windows\System32). So exceptions thrown in assemblies that are hosted in a windows service, the call stack rarely contains the file names and line numbers even when the right PDB files are available.

The working directory of a windows service can be changed using the following line:

   1: Environment.CurrentDirectory = System.AppDomain.CurrentDomain.BaseDirectory;

Once the working directory has been changed to the base directory, the CLR should pick up the right PDB files and the stack trace should contain line numbers.


Technorati Tags: , , ,

Friday, August 31, 2007

Shortcut: Launch Visual Studio Command Prompt from Visual Studio

In Visual Studio 2005:

  1. Go to Tools > External tools
  2. Click Add and enter the following information
    1. Title: Cm&d
    2. Command:  %comspec%
    3. Arguments: /k ""C:\Program Files\Microsoft Visual Studio 8\VC\vcvarsall.bat"" x86
    4. Initial Directory: $(ItemDir)
  3. Click Apply / OK 

In Visual Studio 2008:

  1. Go to Tools > External tools
  2. Click Add and enter the following information
    1. Title: Cmd
    2. Command:  %comspec%
    3. Arguments: /k ""C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"" x86
    4. Initial Directory: $(ItemDir)
  3. Click Apply / OK

Technorati tags: ,

Wednesday, August 29, 2007

Visual C# 2005 shortcuts

I found a nice PDF file that lists the most frequently used shortcuts in Visual C# 2005. You can download it from the Visual C# 2005 Keyboard Shortcut Reference Poster page.

Technorati Tags: ,

Friday, July 27, 2007

Visual Studio 2008 Beta 2 released.

Find it using this link: Visual Studio 2008 Beta 2.

Rob Caron has an easier way to download Visual Studio 2008 Beta 2.

Looking for an easier way to download those huge Visual Studio 2008 Beta 2 files? Go grab the Microsoft Secure Content Downloader from Microsoft Research.

Unfortunately it not install over Beta 1, Beta 1 has to be uninstalled. But it does have a go-live license, which means it can be used in production It also means it very close to being feature complete. I just can't wait for it to be released.

Make sure you read the Installation notes section of Scott Guthrie's blog post. Also Daniel Moth blogs his Visual Studio 2008 installation experience.

Subscribe to my feed in your favorite feed reader