More servicesWindows Live
HomeHotmailSpacesOneCare
 
MSN
Sign in
 
 
Spaces home  MyFunPhotosProfileFriendsBlog Tools Explore the Spaces community

Blog

November 08

New Cider Adorner Placement API's

In my last post I discussed the 3 adorner spaces in the new Cider adorner placement API's.  In this post I will discuss these API's  in a little more detail.  Note at the time of this writing, the spcific class and property names have not been finalized.  jnak will be asking for your input in his blog See Win App.  We'd like to know your thoughts on the names since we traditionally work with a single coordinate system in user interface developement, supporting 3 coordinate systems can be confusing. 

The driving goal of the last set of changes has been to support a concept of layout space.  I've also taken this opportunity to simplify the setting of adorner placement and open the adorner panel arrange so it can be extended by external developers.  I've tried to simplify this so developer can create designer features without dealing with the math am atricies associated with layout transforms, render transforms, right-to-left(RTL) language transforms, and zomming content in the designer view.  With you help we can take this next step at nameing and organizing these classes and properties to make them easiest to use.

Please visit jnak's blog and give us your feedack See Win App.

In this example, the parent grid has a render transform X-skew of 5 degrees. Though this scenario is useful for demonstrating the affects of the different spaces.

Notice the selection frame and grab handles in the grid are unaffected by the skew of the grid render transform. These adorners are adorning the position the grid is within its parent. Since the grid's parent is unaffected by the grid’s render transform, the grid layout space is also unaffected by this transform.

Notice that the button’s selection frame and grab handles ARE affected by the render transform of the grid. Since the layout position of the button is in the coordinate system of the rendered grid, the square layout slot of the button has been skewed by the transform.

 

Scenario: Top Grid Rail

Here is the code for placement of the top grid rail. This adorner is in the render space of the grid, is stretched from the left hand to the right hand side of the grid, is positioned outside the top grid edge, and has a height determined by the adorner XAML style. The height does not scale when the designer zooms in.

// start with empty placement
ContributionGroup placement = new ContributionGroup();
placement.Add(new SizeRelativeToAdornerDesiredHeight(this, 1.0, 0));
placement.Add(new SizeRelativeToContentRenderWidth(null, 1.0, 0));
placement.Add(new PositionRelativeToAdornerHeight(this, 0, -offsetY));
AdornerPanel.SetPlacement(this, placement);
AdornerPanel.SetHorizontalStretch(this, AdornerStretch.Stretch);
AdornerPanel.SetVerticalStretch(this, AdornerStretch.None);

Scenario: TopRightGrabHandle

This adorner is sized to the according to the XAML style. This adorner is positioned in the layout space of the adorned element and positions at the right hand side of the adorned element. The position is adjusted 3 pixels further right and upward by the height of the adorner plus 3 pixels in order to locate it outside of the top right edge fo the adorned element’s layout position.

ContributionGroup placement = new ContributionGroup();
placement.Add(new SizeRelativeToAdornerDesiredWidth(this, 1.0, 0));
placement.Add(new SizeRelativeToAdornerDesiredHeight(this, 1.0, 0));
placement.Add(new PositionAtContentLayoutSlot(null));
placement.Add(new PositionRelativeToContentLayoutWidth(null, 1.0, 0));
placement.Add(new PositionRelativeToAdornerWidth(this, 0, -3.0));
placement.Add(new PositionRelativeToAdornerHeight(this, -1.0, 3.0));
AdornerPanel.SetPlacement(this, placement);

Proposed Placement Classes

Contribution Group

This is a collection of class instances that declare adjustments to the adorner size and position.  This is a temporary name, other names we have tossed around are ArrangementGroup and PlacementGroup.

Please offer you suggestion at jnak's blog.

Adorner Space

The adorner space properties allow you to adjust the size off the adorner based on the desired size determined by the style size of the adorner.  Adorner position can be adjusted relative to the final computed size fo the adorner.  Size and position can also be adjusted in pixels.  Adorner space does nto scale when the designer zooms in/out.

SizeRelativeToAdornerDesiredHeight(relativeTo, factor, offset)
SizeRelativeToAdornerDesiredWidth(relativeTo, factor, offset)
PositionRelativeToAdornerHeight(relativeTo, factor, offset)
PositionRelativeToAdornerWidth(relativeTo, factor, offset)

Render Space

The render space properties allow you to adjust the size or position of the adorner relative to the adorned element and by an offset measured in pixels in thatcoordinate system.  Render space size and positions adjustments are affected by and transform that affects the render size and shape of the adorned element.

SizeRelativeToContentRenderHeight(relativeTo, factor, offset)
SizeRelativeToContentRenderWidth(relativeTo, factor, offset)
PositionRelativeToContentRenderHeight(relativeTo, factor, offset)
PositionRelativeToContentRenderWidth(relativeTo, factor, offset)

LayoutSpace

The layout space properties allow you to adjust the size or position of the adorner relative to the layout slot fo the adorned element and an offset measured in pixels of that coordinate system.  Layout space size and positions are afected by transforms that affect the render space of the adorned element parent.

SizeRelativeToContentLayoutHeight(relativeTo, factor, offset)
SizeRelativeToContentLayoutWidth(relativeTo, factor, offset)
PositionAtContentLayoutSlot(relativeTo )
PositionRelativeToContentLayoutHeight(relativeTo, factor, offset)
PositionRelativeToContentLayoutWidth(relativeTo, factor, offset)

November 07

Layout Space Adornment in Cider

I have recently been redesigning the architecture used to specify adorner placement within Cider.  This is a good time for us to get to a common understanding of the coordinate systems that affect our adorners in WPF and how they can affect the designer surface.

First, I suggest thinking of render space as a child of layout space. Then the layout moves, the render space moves accordingly.

Next note that render space can move in relation to layout space. This movement can be in any direction and can even place the rendered control outside of the layout space entirely. Render space can also be used to scale and element to be larger or smaller than the layout size of the element.

Consider the following example, the button has been scaled down in size using a RenderTransform with scale dimensions less than 1.0.

Layout properties in WPF such as Margin, Grid.Row, Grid.Column, Width, Height affect the layout space of the element and are relative to the render space of the parent element. So when we talk about the layout space of an element this maps to the render space of the element’s parent.

Any adorners which interact with these layout properties must also be placed in the layout space. Grab handles or resize adorners for instance are in layout space since they are directly displaying and affecting the layout. In the example given, the grab handles appear some distance away from the edge of the button because they are not affected by the render transform causing the button to be smaller than the space given to it by the layout properties.

The adorner space is used to define dimensions of the adorner that do not change in size when the designer surface is zoomed.  (Yes, Cider generally supports zooming.  The Cider team has not yet had the time to design the UI and verification tests in order to insure zooming is a high quality experience.)

Most commonly adorner developers are adorning content displayed witin the render space of a control.  Layout space adornments will be needed if you are implmenting a layout tool or custom panel adorners. 

This new design allows adorners to be easily created in the layout space as well as the render space, or the designer view space as before.  Feature designers should consider which space they expect to adorn.  If in doubt, I'd suggest applying a render transform as I did above.  And design your adorners with this distinct difference between the layout space and render space. 

In a later post I will discuss the properties used to position adorners. 

November 02

XNA GSE - Free Game Development Tools

If you have a machine still running Windows XP SP2 and you'd like to play with some fun simple game development code, check out XNA Game Studio Express. 

http://msdn.microsoft.com/directx/xna/gse/

This install requires Visual C# Express to first be installed.  Visual C# Express can co-exist with the full versions of Visual Studio and does not share any settings, so will not interfere in any way. Visual C# Express Download Page

What is GSE?

GSE is a game development environment for Visual Studio.  GSE is provided to the community to stimulate a healthy hobbyist and student game development ecosystem.  By having a common (and free) platform people can develop, learn and share games and code libraries.

Where can GSE created games run?

Currently on Windows computers.  Next they will be able to run on Xbox 360 systems.  Beyond that, the imagination is the limit.  Keeping in mind that basic graphics services and 3D rendering are needed.

What's the best way to get started?

Install Visual C# Express.  Then install GSE.  Open Visual C# Express and Create New Project.  Choose "Space Wars Project"

Space Wars

Space Wars is a sample project that implements a simple game.  This game watches user input, loads and renders graphics, plays sounds, ad simulates some simple physics.  There is plenty here to explore.

Read more about the history of Spacewar!

In my next post I will give a bit of a tour of the Space Wars sample.

WPF Rendering - #1

WPF offers distinctly different techniques for rendering graphical elements. The top level is adding shape elements such as Rectangle, Ellipse, and Path to a Panel element. This is what we see in the multitude of XAML based samples. Below I explore another technique involving implementing OnRender on a class derived from UIElement.

Rendering within UIElement::OnRender()

Implementing within UIElement is accomplished by implementing OnRender. OnRender is provide with DrawingContext. This context offers methods for drawing text and geometry.

class UIElmentOnRenderDemo : UIElement {
    protected override void OnRender(DrawingContext drawingContext)   { … }
}

When the parent of the UIElement detects that the size has changed, OnRender is called. Within OnRender we can generate render geometries and make calls to the drawing context to render them.

Rect rect = new Rect(new Point(5, 10), new Size(100, 20)));

Geometry outline = new RectangleGeometry(rect);

drawingContext.DrawGeometry( brush, pen, outline);

Note that the rectangle was intended to be rendered with a single pixel line and is showed at thicker with sfoter edges. The is result of "anti-aliasing" in order to soften the images on eh screen. Here is a close-up.

RenderOptions.SetEdgeMode can be used to turn off antialiasing for all non-text render output within the UIElement. Setting Edge mode for individual geometry has no effect. EdgeMode has no effect on text rendering.

RenderOptions.SetEdgeMode(this, EdgeMode.Aliased);

With EdeMode set on UIElement the rectangle is rendered crisply. 

Note: I'll be invesigating rendering in more depth in upcoming blog entries.  Problems arise when rendering on 120 DPI displays.  I'll also delve into more complex geometries and the use of guidelines.

Nikola Is Blogging!

Nikola is one of the QA members of the Cider Team.  He is now blogging at http://blogs.msdn.com/nikola/. Be sure to check it out and encourage him to blog more.

Back from Vacation

Well, I've survived yet another vacation.  After 1900 miles, 5 states, 8 tanks of gas, 5 hotels, 2 horseback rides I return home with 8 gigabytes of photos, aches, pains, more bug bites than I can count, and fine new pair of cowboy boots, and ready get working on Cider again!

NetFx3.com – Developer community for the .NET Framework 3.0

 .Net Framework 3.0 has been announced.  It includes Windows Workflow Foundation, Windows Communication Foundation, Windows Presentation Foundation, and Windows CardSpace.  A new community site has been launched to support this, NetFx3.com

 

Check it out, sign up, and contribute!

Cider Grid Layout Experience

For the May CTP we have improved the reliability of the Grid layout in Cider.  I'd like to hear your thoughts on how you like the features.  Particularly resizing the columns using the triangular handles verses the thin line of the column results in a different adjustment of the margins of controls within the grid. 

 

Currently we do not modify MinSize for grid children.  When resizing a grid with buttons in it, the buttons will begin to clip when the space of the column span minus the left and right margins is less than the MinWidth of the button (which defaults to 75 pixels).

 

 How to you think Cider should deal with MinWidth and MinHeight?  In order to avoid clipping, we either need reduce the MinWidth or reduce margins and perhaps increase the ColumnSpan.  This problem is complicated when multiple controls (grid children) are affected at once.

'Microsoft Brews Some Cider'

Patrick Meader, Editor in Chief of Visual Studio Magazine, talks about Cider in the February issue.  Brian Pepin had his blog mentioned as well.  In Monday's architecture meeting I got Brian to sign my copy 8-)  I'm sure I'll fetch a handsome price on Ebay at some point in the future.

 

http://www.ftponline.com/weblogger/forum.aspx?ID=6&DATE=01/26/2006&blog=#518

Slacking Blog and Cider Jan CTP release, Sparkle's First CTP!

Well it’s been a few days since I have blogged.  I’m sorry.  Mostly the blame is on me.  A little I will put on Rob Caron who loaned me season 1 of both Lost and 24.  Both I really enjoyed at the expense of my time i normal spend finding interesting bits to blog.

We have released our second CTP of Cider!  We’d very much like to hear your feedback on the Grid designer user experience. Cider Jan CTP can be downloaded here.

http://www.microsoft.com/downloads/details.aspx?FamilyId=5A0AE4CD-DC79-4B12-8A05-B6195F89FFA2&displaylang=en

 

Congratulations to the Sparkle team for their first CTP of the Expression Interactive Designer.  It can be downloaded here:

http://www.microsoft.com/products/expression/en/interactive_designer/id_free_trial.aspx

Thanks for all the regular traffic to this blog.  It is inspiring to see that you find this interesting. 

I have two requests for you, the reader…

First: I’d like to hear more about how you use XAML to layout your forms.  This will help me to understand the workflow and thought processes you use in creating your apps.  How can we improve this layout process in the visual designer?  Send me interesting XAML you have created so I can see how you are using the Avalon controls and panel.  We have found here that 3 people given the same goal form often implement it 3 different ways.

Second: Feedback on my blog is VERY welcome, and inspiring.  Criticism, Praise, and suggestion about what you’d like to see will all motivate me and reward me for the effort it takes to blog regularly. 

In advance, Thanks!

Richard

3D WPF centric blog

Today I enjoyed reading through Andrej's blog and website.  He's been focusing on 3D graphics within WPF.  A fun topic indeed.

Textbox with spell checking

WPF TextBox and RichTextBox include an optional speeling checker.  Simply set IsSpellCheckEnabled=”True”

<TextBox Width="200" Height="30" IsSpellCheckEnabled="True">Freee spell cheker!</TextBox>

Spell1

Right-Click shows optional alternate words in dictionary.

Binding properties

Binding is core to WPF and take many forms.  In this sample, I bind the width of my button control to the value of mySlider.  As mySlider moves, its value changes from 10 to 100 and the Width of my button follows.

<Slider Name="mySlider" Minimum="10" Maximum="100"/>
<Button Width="{Binding Value,ElementName=mySlider}">
   
Stretchy Button
</
Button>

  

WrapPanel Introduction

The WrapPanel performs a useful flow type layout of content items with wrapping to prevent clipping on right (or left for right-to-left layout). 

WrapPanel

 <WrapPanel Width="200" Height="100"
        Orientation="Horizontal" >
       <
TextBlock >WrapPanel</TextBlock>
       <
Button >Button1</Button>
       <Button >Button2</Button>
      
<Button >Button3</Button>
       <
Button >Button4</Button>
       <
Button >Button5</Button>
       <
Button >Button6</Button>
       <
Button >Button7</Button>
</
WrapPanel>

Charles' WPF Book

I look forward to reading Charles Petzold's new book: "Application = Code + Markup."  Also, thanks to Charles for mentioning this blog in his.

Really Simple RSS

Data binding is one the the pillars of XAML development.  Rather than writing code that must execute to copy data from one place to another (i.e., from files to the screen), we define relationships between elements on screen, in-memory, or in files.

A binding defines a source of data and a destination.  In this example, for the source, I define an XmlDataProvider that loads the RSS feed of this blog.  The blog entries of an RSS feed are under the <rss> tag AND the <channel> tag; this is the XPath specified as "rss/channel" I give the XmlDataProvider a name of "RichardsBlog"

  For the destination I use a Listbox.  I must tell the Listbox where the data will come from.  This is called the DataContext which I set to the name "RichardsBlog".  I also must tell the Listbox what data to use for the content of each item.  Within the RSS feed channel, each entry is within the <item> tag and the title is within the <title> tag.  I use these to tell the Listbox that the XPath of the binding is item/title.

<XmlDataProvider x:Key="RichardsBlog" 
     XPath="rss/channel" 
     Source=http://blogs.msdn.com/richard_bailey/rss.aspx>
</XmlDataProvider>

<ListBox DataContext="{StaticResource RichardsBlog}"
         ItemsSource
="{Binding XPath=item/title}"/>
 

 That's it.  Here is the result.

Thanks to Rob

Thanks to Rob Caron for linking to my blog and boosting traffic in my direction. I hope to learn much about effective blogging from Rob and perhaps from those who read this blog.  Please send me feedback how this this blog is useful and not.

Adding hotkeys to labels in WPF forms

Earlier today I was chatting with jfo about adding hotkeys to labels and moving focus to a textbox.

<Label Target="{Binding ElementName=textBox1}"
   
Width="Auto" Height="Auto" Name="label1">
    _First name:

</
Label>
<
Label Target="{Binding ElementName=textBox2}"
    Width
="Auto" Height="Auto" Name="label2">
    _Last name:

</
Label>
<
TextBox Width="Auto" Height="Auto" Name="textBox1"></TextBox>
<
TextBox Width="Auto" Height="Auto" Name="textBox2"></TextBox>

Underscores in the label text chooses what character is hot for that label.  Pressing alt will show the character underlined if it is not always in your windows configuration. 

Target="{Binding ElementName=textBox2}"

Tells the label where to move the focus when the hotkey is pressed.

Here is the resulting app:

Absolute versus Auto Sizing

 One big advantage of WPF versus other layout tools is it's ability to automatically resize forms and controls based on the size of their content.  A tradeoff here is the ability to control "exactly" what the layout looks like.  A button may be a little longer to fit a name or some text localized to German.  In order for this to work, the properties for controls should be "sparsely populated."  This means that the Width of a button should be left empty if the size of the button should increase to fit the text on the button.

 

This button is positions at 73, 41 within the grid call at Row 0 Column 0 

<Button VerticalAlignment="Top" HorizontalAlignment="Left"

Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="0" Grid.RowSpan="1"

Margin="73,41,0,0" Width="75" Height="23" Name="button3">

ButtonTextReallyLong

</Button>

Note that this button sits within a single row and single column, hence the RowSpan and ColumnSpan are both set to 1.  Note also that the Width of the button is set to 75.  This button ends up being shorter than the text.

 

 

An improved button does not set the redundant properties and leaves with width at Auto

<Button VerticalAlignment="Top" HorizontalAlignment="Left"

Grid.Column="0" Grid.Row="0"

Margin="73,41,0,0" Name="button3">

ButtonTextReallyLong

</Button>

Note that the HorizontalAlignment and VerticalAlignment must be set in order to prevent the stretching of the bottom to the right and bottom edges of the cell.

 

 

Actually in this example the Row and column do not need to be set either since 0,0 is the default row and column.  Although I find that having these be set helps each of my controls seem more consistent in the XAML.

First Cider CTP

We have released our first CTP of Cider.  View the announcement in the Cider Forum.

If you'd like to try it out, I'd suggest installing in this order:
   Step 1) WinFX 
   Step 2) Windows SDK 

         Install Instructions are located at linked page under "instructions".

         My Steps:

               Step 2a) download 6.0.5270.0.9.WindowsSDK_Vista_idw.DVD.Rel_Update.img

                      2b) install the Virtual CD-ROM Control Panel for Windows XP

                      2c) extract files to local disk; follow instructions in readme.txt to open ISO image file.

                      2d) run Setup.exe

   Step 3) Visual Studio code name 'Orcas' CTP – Win FX Development Tools 
  
  
This is our first release from the Cider team and is the result of much hard work on our M3 milestone.  Also, view the Channel 9 Cider Wiki site.