Welcome to MSDN Blogs Sign in | Join | Help

Whats coming in VS 2010 - WPFDesigner.

Mark Wilson-Thomas (PM on Cider team) gives a sneak-preview of whats coming in VS 2010 : http://channel9.msdn.com/shows/The+Knowledge+Chamber/Mark-Wilson-Thomas-WPF-and-Silverlight-Development-in-Visual-Studio-2010/

- Enjoy!

Posted by subhagpo | 1 Comments
Filed under:

XAML PowerToys for VisualStudio!

Karl (our newest PM on the team) presented cool power tool that enable developers to quickly layout and maintain Line of Business Application forms using the UI controls that ship with Visual Studio.
More here : http://karlshifflett.wordpress.com/xaml-power-toys/
Posted by subhagpo | 1 Comments
Filed under:

PDC unleashed ...

When you have a chance watch the great stuff that was showcased at PDC here
Posted by subhagpo | 1 Comments
Filed under:

WPF and VS updates at PDC 2008

Here's a great post by Tim Sneath that talks about new features in WPF and VS-shell. : http://blogs.msdn.com/tims/archive/2008/11/03/wpf-developers-pdc-wrap-up-and-visual-studio-tooling-update.aspx

 

Posted by subhagpo | 1 Comments
Filed under:

first blog for cider !

This is my first blog since I have changed teams last year. Wow, its almost 5 months since I am in this new team and there are no excuses for not blogging.

I have decided to actively start blogging about this very cool technology that I am working on which is called Cider. I know you will ask "Cider.. what is that?". BrianPe has already explained it here. We are building a designer for WPF technology thats going to ship with Visual Studio.

We have adopted the new agile process of developement and have already shipped some CTPS (the most recent was the Feb CTP).

Instead of starting the first post with the customarty "Hello world" application, I will just provide some links to the blogs of my team members (who are active bloggers than myself)

BrianPe: http://www.urbanpotato.net/Default.aspx/document/970

ChuckJ: http://www.removingalldoubt.com/

Jfosler: http://blogs.msdn.com/jfoscoding/archive/category/11634.aspx

RBailey: http://blogs.msdn.com/richard_bailey/

 

Posted by subhagpo | 0 Comments
Filed under:

What's new in Whidbey? : Part 1 - ClipBoard Improvements.

   There are lots of new things in the Whidbey release for Windows Forms. 

 

   There are a bunch of new controls and components like StripControls (ToolStrip, MenuStrip, ContextMenuStrip, StatusStrip), DataGridView, SplitContainer, WebBrowser. We have also added some richness to existing controls and components. For example we have exposed the scrollbars on scrollablecontrol as properties, added a bunch of new properties to the treeview and the tooltip, provided auto complete feature on the combo-box and the text-box and added list-view virtualization.

   In the designer space we have exposed a framework to build simple light weight designers that automagically uses the new serialization code, snaplines and other designer features. We have added snap-lines and a new mechanism to show the properties that are commonly used which we call the smart-tags extension. We have also enabled configuration settings management and provided extensible interfaces for the users to plug-in their own configuration settings.

    In order to explain some of the new features in Whidbey, I have decided to take one feature at a time and explain how it works and how it can be used. I will also try to explain how it is different (and easy) to use the same feature in Whidbey as compared to Everett (if applicable). So let’s get started...

 

ClipBoard:

 

   ClipBoard is an existing class from Everett which can be found in System.Windows.Forms namespace. The basic functionality of this class is to allow user to set data into the clipboard and retrieve it. This is how the class looked in Everett

 

public sealed class System.Windows.Forms.Clipboard :
    object
{

    // Constructors

    // Methods
    public virtual bool Equals(object obj);
    public static System.Windows.Forms.IDataObject GetDataObject();
    public virtual int GetHashCode();
    public Type GetType();
    public static void SetDataObject(object data);
    public static void SetDataObject(object data, bool copy);
    public virtual string ToString();
} // end of System.Windows.Forms.Clipboard

 

   The user can use the SetDataObject to place the data on the clipboard. The bool “copy” denotes if the data should remain on the clipboard after the application exits.

Consider a form with a picture box and a button. The following code would place the image of the picture box on the clipboard.

 

private void button1_Click(object sender, System.EventArgs e)

{

// Takes the image and puts it on the clipboard.

      if(this.pictureBox1.Image != null)

            Clipboard.SetDataObject(this.pictureBox1.Image, true);

}

 

   Now consider another application which has a panel and a button. Now you can set the background image of the panel to the image of the picture box that was copied to the clipboard earlier using the following code.

 

private void button2_Click(object sender, System.EventArgs e)

{

// Declares an IDataObject to hold the data returned from the   // clipboard.

      // Retrieves the data from the clipboard.

      IDataObject iData = Clipboard.GetDataObject();

      // Determines whether the data is in a format you can use.

      if(iData.GetDataPresent(DataFormats.Bitmap))

      {

            // Yes it is, so display it.

this.panel1.BackgroundImage = (Bitmap)iData.GetData(DataFormats.Bitmap);

      }

      else

      {

            // No it is not.

            this.Text = "Could not retrieve data off the clipboard.";

      }

}

 

   In Whidbey the ClipBoard class looks as follows:

 

public sealed class System.Windows.Forms.Clipboard :
    object
{

    // Constructors

    // Methods
    public static void Clear();
    public static bool ContainsAudio();
    public static bool ContainsData(string format);
    public static bool ContainsFileDropList();
    public static bool ContainsImage();
    public static bool ContainsText();
    public static bool ContainsText(System.Windows.Forms.TextDataFormat format);
    public virtual bool Equals(object obj);
    public static System.IO.Stream GetAudioStream();
    public static object GetData(string format);
    public static System.Windows.Forms.IDataObject GetDataObject();
    public static System.Collections.Specialized.StringCollection GetFileDropList();
    public virtual int GetHashCode();
    public static System.Drawing.Image GetImage();
    public static string GetText();
    public static string GetText(System.Windows.Forms.TextDataFormat format);
    public Type GetType();
    public static void SetAudio(byte[] audioBytes);
    public static void SetAudio(System.IO.Stream audioStream);
    public static void SetData(string format, object data);
    public static void SetDataObject(object data);
    public static void SetDataObject(object data, bool copy);
    public static void SetDataObject(object data, bool copy, int retryTimes, int retryDelay);
    public static void SetFileDropList(System.Collections.Specialized.StringCollection filePaths);
    public static void SetImage(System.Drawing.Image image);
    public static void SetText(string text);
    public static void SetText(string text, System.Windows.Forms.TextDataFormat format);
    public virtual string ToString();
} // end of System.Windows.Forms.Clipboard

 

 

   A bunch of static helper functions have been added to the ClipBoard class that would wrap the data in the DataObject and pass it onto the clipboard in the correct format. The ContainsXXX methods can be used by the user to query the current contents of the clipboard without actually getting the IDataObject from the clipboard and calling GetDataPresent on it. The helper functions are provided on commonly used DataFormats but users can still use the old SetDataObject and GetDataObject for custom formats.

   In Whidbey, you can programmatically clear the clipboard calling the Clear method. This removes all the contents of the clipboard and can be helpful if you want to purge the contents of the clipboard periodically.

 

   Coming to the same example that we discussed above, the same code in Whidbey would look like the following:

 

private void button1_Click(object sender, EventArgs e)

{

// Set the image (this will throw an exception if image passed in // is null)

     Clipboard.SetImage(this.pictureBox1.Image);

}

 

private void button2_Click(object sender, EventArgs e)

{

     // Check if ClipBoard has image...

     if (Clipboard.ContainsImage())

     {

         // if so, set the image to the background image of the panel

         this.panel1.BackgroundImage = Clipboard.GetImage();

     }

     else

     {

         this.Text = "No Image in ClipBoard";

     }

}

 

   As you can see the code here is greatly reduced as compared to Everett and most of the work is done by the clipboard class. The user just needs to call the proper helper functions.


 

Whidbey security restrictions using ClipBoard

 

   Clipboard works for application running under STA apartment thread only. More information about STA and MTA thread can be found here. In full-trust the clipboard allows to set and get any data. In partial trust (Internet zone) data only in the following four formats can be set into the clipboard:

 Formats allowed: Text, UnicodeText, System.String and CSV.

All other formats are restricted in partial trust.

 

Coming up next is TreeView... so stay tuned.

Posted by subhagpo | 0 Comments
Filed under:

How can I drop controls within UserControl at Design time?

One of the most frequent questions asked on the community forum is how can I make my userControl act as a containerControl (panel) which allows me to add controls at design time. In V1.0 and V1.1 you had to write a lot if code to do this, but in Whidbey we have added a new concept of NestedContainers which would allow the users to accomplish this using a single method on the ControlDesigners.

Let me explain how you can expose the userControl as "container" at design time.

You may ask why doesnt it work by default?

What you’re seeing is our default encapsulation model for user controls.  By default, a user control is treated as a single object when placed on a form.  We do this because it may not be your intent to expose the inner layout of your user control (for example, the PropertyGrid control contains several panels, buttons, scroll bars, etc, but it is treated as a single control). So there are cases when you want the userControl to be a single composite control and hence not support it as container at design time. This still remains the default case in whidbey too.

What should I do to make the control act as container at Design time?

This is easy to do.  You need to change the designer on your user control:

[Designer(typeof(ParentControlDesigner))]

public class MyUserControl : UserControl {}

Once you do this, the user control can be edited on the form designer’s surface.If you want a region of “content” on your user control to be interactive at design time…

This is the more likely case – you have a control with some child controls on it, but one (or more) of the child controls needs to be a content area where the user can drop additional controls.  Within this content area you want the user to be able to select, drag, drop and otherwise manipulate controls, but outside of the area you want the user control to be treated as a single entity. In whidbey, you need to do two things:

1)  Add a public read-only property to your user control that exposes the child content control. Write a simple designer that enables the content control to be designed. 

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]

public Panel MyChildPanel { get { return _myChildPanel; } }

The attribute on the property tells the code generator to write out code for the value contained in this property (normally, read-only properties are skipped).

2) Use EnableDesignMode method to plug in the designer for panel.

[Designer(typeof(MyUserControlDesigner))]

public class MyUserControl : UserControl {

}

class MyUserControlDesigner : ControlDesigner {

      public override void Initialize(IComponent comp) {

            base.Initialize(comp);

            MyUserControl uc = (MyUserControl)comp;

            EnableDesignMode(uc.MyChildPanel, “MyChildPanel”);

      }

}

Here I’ve created a designer (which can…and should be an internal class unless you specifically design for extensibility).  In the initialize code for the designer I’ve called EnableDesignMode, passing the panel I want to enable (MyChildPanel), and a text name that will be shown to the user when the panel is selected (“MyChildPanel”). 

Once you do this, the panel will work in the designer.  If you click on it, it will be selected and you can set properties on it in the property window.  The name for the selected panel will be a mix of the control’s name and the name you provided.  For a control named myUserControl1, the panel’s name in the grid will show up as “myUserControl1.MyChildPanel”.

I will discuss the basics of EnableDesignMode in a separate blog entry.

 

Posted by subhagpo | 2 Comments
Filed under:

Mark Boulter video...

Mark Boulter (Technical Lead PM) Dot Net Client team explains the new features for Whidbey.

He explains his definition of "smart" clients in the first half and then talks about his work here at Microsoft.

Here's the complete interview

Part1 

Part2

 

Posted by subhagpo | 1 Comments
Filed under:

Microsoft Research ...

Soma's blog describes some of the projects that have been undertaken by Microsoft Research lab.

Posted by subhagpo | 1 Comments
Filed under:

What is Control.SelectNextControl(...)?

Today I recieved a question on Winforms discussion list about SelectNextControl function on control and I thought it might be worth sharing some thoughts on this topic. The name "SelectNextControl" suggests that this function would select the next control in the taborder starting from the control on which this function is called. But THAT’S NOT THE CASE.

Infact, this function tries to select the next "child" control (in the taborder) of the control on which this function is called. Let me explain with a scenario to make this point easy to understand. Say you have a form which has couple of textBoxes and a button. In the button click you want to change the focus to the next control in tarorder from the Button. (which is the ActiveControl on the Form when you click it) 

The Following code is WRONG:

private void button1_Click(object sender, System.EventArgs e)

{

        ((Button)sender).SelectNextControl(ActiveControl, true, true, true, true);

}

 

The above code would try to select the next control within Button and since there is NO child control within button this will just be a NO-OP.

What you really want is to do the following:

 

private void button1_Click(object sender, System.EventArgs e)

{

         Control parent = ((Button)sender).Parent;

         parent.SelectNextControl(ActiveControl, true, true, true, true);

}

So be careful about using this function as the MSDN help doesnt explicity mention this behavior.

 

Posted by subhagpo | 4 Comments

Whats the difference between Control.Invalidate, Control.Update and Control.Refresh?

Control.Invalidate() v/s Control.Update() v/s Control.Refresh()

 

Before discussing each one of the above functions, let’s look at how winforms controls paint.

 

Windows controls paint is response to WM_PAINT messages. This message is sent when UpdateWindow or RedrawWindow is called, or by the DispatchMessage function when the application gets a WM_PAINT through the message queue. On getting the WM_PAINT message, the control paints its background and then the foreground if necessary. Double-buffering and transparency is honored while painting and then the OnPaint event is fired to give the user a chance to perform his custom painting.

 

With this background, let’s look at the above mentioned three functions in more detail,

 

Control.Invalidate( ) / Control.Invalidate(bool) / Control.Invalidate(Rectangle) / Control.Invalidate(Rectangle, bool) / Control.Invalidate(Region) / Control.Invalidate(Region, bool)

 

            The bool parameter denotes whether the user wants to invalidate the child controls of the control on which he is calling Invalidate. The Rectangle parameter are the bounds to invalidate and the region parameter is the region to invalidate. All the overloads essentially end up calling one of the RedrawWindow, InvaliateRect or InvalidateRgn functions. If RedrawWindow is called then this may result in a WM_PAINT message being posted to the application message queue (to invalidate the child controls).

            The important thing to note here is that these functions only “invalidate” or “dirty” the client area by adding it to the current update region of the window of the control. This invalidated region, along with all other areas in the update region, is marked for painting when the next WM_PAINT message is received. As a result you may not see your control refreshing (and showing the invalidation) immediately (or synchronously).

 

Control.Update()

 

Update function calls the UpdateWindow function which updates the client area of the control by sending WM_PAINT message to the window (of the control) if the window's update region is not empty. This function sends a WM_PAINT directly to WNDPROC() bypassing the application message queue.

Thus, if the window update region is previously “invalidated” then calling “update” would immediately "update" (and cause repaint) the invalidation.

 

Control.Refresh()

 

            By now, you might have guessed what Refresh( ) would be doing. Yes, it calls Invalidate(true) to invalidate the control and its children and then calls Update( ) to force paint the control so that the invalidation is synchronous.

Posted by subhagpo | 2 Comments
Filed under:

How can TypeDescriptor and TypeDescriptionProvider be used?

Brian explains how these features in whidbey can be used to design abstract forms.

As usual, a great post by Brian.

 

Posted by subhagpo | 0 Comments
Filed under:

Winforms Tips and Tricks:

Coding:

 

1)       Use BeginUpdate( ) and EndUpdate( ) while performing any bulk operation that would cause the window to redraw itself.

a.       Large number of items to ListView.

b.       Large number of nodes to TreeView.

 

BeginUpdate() sends a WM_REDRAW message passing FALSE as redraw state to the window. This stops any paint messages being sent or processed. After the bulk operation is done EndUpdate( ) should be called which sends a WM_REDRAW message passing TRUE as redraw state. This is followed by calling Invalidate( ) which adds a rectangle (normally this is the clientRectangle) to the specified window's update region. The update region represents the portion of the window's client area that must be redrawn when the window receives the next WM_PAINT message.

 

We provide this public API on the controls that need it like ComboBox, ListBox, ListView, TreeView. Thus following a call to BeginUpdate(), any redrawing caused by operations performed on the above mention controls is deferred until the call to EndUpdate().

MSDN help here 

 

2)       When list box is bound to a datasource he SelectedIndexChanged event fires 3 times.  If you set the datasource after the valuemember and displaymember then the selectedindex is only fired once.

 

3)       How Should the SelectedIndex event handled? 

You should set the DataSource last.  You can’t prevent SelectedIndexChanged from firing because the SelectedIndex does change (from -1 to 0).

 

4)       Is there any reason why Datasource should be set first? 

This is more efficient.  Setting the DisplayMember after the DataSource will cause the ComboBox to rebind (re-populate).

 

5)       You might experience that if you set the datasource after displaymember and valuemember, the displaymember gets reset to string.Empty.  Why does this happen?

This happens if you set the DataSource to null.  So if you set the DataSource to a valid  value, then clear it by setting it to null, then back to a valid value you’d wipe out your DisplayMember.

 


 

Performance:

 

1)       Use ResumeLayout( ) and SuspendLayout( ) pair while performing operations that would cause the control to Layout. As an example think of a Form that hosts controls that are laid out depending on the size of the Form. In this case as the Form size changes, all the controls are laid out and this would cause a lot of flicker while changing the size of the form (say through mouse drag). But you can call SuspendLayout( ) on the Form’s ResizeBegin( ) and ResumeLayout( ) on the Form’s ResizeEnd( ) and thus the layout happens only once, that is at the end of the Form's size change.

MSDN help here

 

2)       Always set the Sorted property of the TreeView after adding the nodes if your are using the ADD method instead of using the AddRange. We call BeginUpdate and EndUpdate APIs while sorting if we know the number of nodes in the TreeView and that makes this approach faster than setting the Sorted property first and then adding nodes to the TreeView. As suggested earlier always use AddRange (since this would use BeginUpdate/EndUpdate by default) or else if you have to use Add then guard it by BeginUpdate and EndUpdate callss

 


Security:      

 

1)       Always use Declarative security (whenever possible) in your code when you are using Code Access Security than Imperative security. Imperative security uses managed objects to specify permissions and security actions during code execution, as opposed to declarative security which uses attributes to store permissions and actions in metadata. Imperative security is extremely flexible since you can set the state of a permission object and select security actions using information that is not available until runtime. With that flexibility is the risk that the runtime information you use to determine permission’s state does not remain unchanged while the action is in effect. Use declarative security whenever possible. Declarative demands are easier to understand and can be detected by tools such as Permview.exe.

Posted by subhagpo | 1 Comments
Filed under:

Microsoft Win32 to Microsoft .NET Framework API Map

This is a great one stop shop for 1.0 and 1.1. APIs that map to there corresponding Win32 APIs.

Posted by subhagpo | 1 Comments
Filed under:
More Posts Next page »
 
Page view tracker