DCSIMG
How to Indicate Unsaved Changes in TFS 2010 Build Definition Custom UI Type Editor - Oshry Horn

Oshry Horn

How to Indicate Unsaved Changes in TFS 2010 Build Definition Custom UI Type Editor

(* – Asterix mark on the parent window)

When I built my own custom UI type editor it was fairly easy, and fully functional.

There was only one bug: when changing (editing) the object in the custom editor, the build definition window did not indicate to me that I had unsaved changes.
Beyond this being extremely annoying, it is also a huge problem because if I close the window I will not know that my changes where not saved (in the case I did not save them).

For this example I will use the Credentials Editor which was posted by Ewald Hofman here.

The Credential object code:

   1: namespace BuildTasks.CustomType
   2: {
   3:     public class Credential
   4:     {
   5:         public string UserName { get; set; }
   6:         public string Password { get; set; }
   7:  
   8:         public override string ToString()
   9:         {
  10:             return UserName;
  11:         }
  12:  
  13:     }
  14: }

This is the code of the UI editor:

   1: using System.Drawing.Design; 
   2: using System.Windows.Forms.Design; 
   3: using System.ComponentModel; 
   4: using System; 
   5: using System.Windows.Forms; 
   6:  
   7: namespace BuildTasks.CustomType 
   8: { 
   9:  
  10:     class CredentialEditor : UITypeEditor 
  11:     { 
  12:  
  13:         public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) 
  14:         { 
  15:             if (provider != null) 
  16:             { 
  17:                 IWindowsFormsEditorService editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService)); 
  18:  
  19:                 if (editorService != null) 
  20:                 { 
  21:                     Credential credential = value as Credential; 
  22:  
  23:                     using (CredentialDialog dialog = new CredentialDialog()) 
  24:                     { 
  25:                         dialog.UserName = credential.UserName; 
  26:                         dialog.Password = credential.Password; 
  27:  
  28:                         if (editorService.ShowDialog(dialog) == DialogResult.OK) 
  29:                         { 
  30:                             credential.UserName = dialog.UserName; 
  31:                             credential.Password = dialog.Password; 
  32:                         } 
  33:                     } 
  34:                 } 
  35:  
  36:             } 
  37:  
  38:             return value; 
  39:              
  40:         } 
  41:  
  42:         public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) 
  43:         { 
  44:             return UITypeEditorEditStyle.Modal; 
  45:         } 
  46:     } 
  47: } 

The solution was found by my friend Shai Raiten.

The solution is:

The build definition property grid das not recognize changes in the object, therefore we must return a completely different object.

There are 2 possible ways to do this:

1) Use the NEW phrase and to populate the properties accordingly

2) Use a DeepCopy() function. (Recommended for more complex objets)

Now your editor will indicate unsaved changes to the user.

Important: If you use the second option (DeepCopy() function) notice that it could be problematic due to the fact that for the deserialization  process your objects assembly will be loaded at runtime automatically and cause the following exception to be thrown:

{"Unable to find assembly 'BuildTasks, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'."}

image

The solution for this issue can be found here!

Comments

Problem Deserializing Classes From Assemblies Loaded at Runtime Implicitly ??? TFS Build Custom UI Type Editor - Oshry Horn said:

Pingback from  Problem Deserializing Classes From Assemblies Loaded at Runtime Implicitly ??? TFS Build Custom UI Type Editor - Oshry Horn

# March 2, 2011 8:25 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: