Rob Relyea

xaml:Blog

  • Tim's tips for learning WPF

    Filed under:

    Tim Sneath posts a good set of resources to start your journey with WPF.

    He references my PDC 2005 Lap around WPF talk.  I wonder how that talk would change with more mature tools now?
    I'm beginning to post information for each of my talks (including my demo script, etc...).  If you are interested, check it out.

    My PDC 2003 talk was better rated by attendees than this talk...

    PostTypeIcon
    6,640 Views
  • Article about WPF Commands

    Filed under:

    Jelle Druyts wrote a nice article about WPF Commands that recently was posted here.

    Give him any feedback here.

     

    Would be interested in Nick Kramer's feedback on the article...he is the PM for WPF commanding...

    Update: Mike Taulty comments here. (adding a link to a writeup IanG did last year)

    PostTypeIcon
    10,870 Views
  • Wpf Xaml Namespace Update Tool for Feb2006 CTP

    Filed under: ,

    When we ship the Feb 2006 CTP, there are a few changes that will need to be done to all xaml files.

    We've created a tool to help upgrade your WPF XAML files to the Feb CTP.  It doesn't do an exhaustive upgrade, but it does handle the following major changes:

    • Change all xmlns uris of http://schemas.microsoft.com/winfx/avalon/2005 to http://schemas.microsoft.com/winfx/2006/xaml/presentation
    • Change all xmlns uris of http://schemas.microsoft.com/winfx/xaml/2005 to http://schemas.microsoft.com/winfx/2006/xaml
    • Replaces all mapping PIs with the new clr-namespace uri syntax:
      • Old Syntax 1
        • <?Mapping ClrNamespace="MyNS" XmlNamespace="other" Assembly="MyAssembly" ?>
        • <Page ... xmlns:foo="other">
      • Replacement Syntax 1
        • <Page ... xmlns:foo="clr-namespace:MyNS;assembly=MyAssembly">
      • Old Syntax 2
        • <?Mapping ClrNamespace="MyNS" XmlNamespace="local" ?>
        • <Page ... xmlns:foo="local">
      • Replacement Syntax 2
        • <Page ... xmlns:foo="clr-namespace:MyNS">
    • Ensure all RowDefintion and ColumnDefinition elements are not direct children of Grid.  They must be in a Grid.RowDefinitions or Grid.ColumnDefinitions property element.

    Note: don't do this until the FebCTP is out...Those URIs won't work in the Jan CTP.

    To download this tool, please see: http://robrelyea.com/tools/XamlMigrate/

    PostTypeIcon
    30,361 Views
  • WPF Attached Properties

    Filed under:

    post on the Avalon Forum from Jaffi raised a question

    WPF is not straight forward. Simple actions, like setting rectangles X position, requires using myRectange.SetValue(Canvas.LeftProperty, Value). I'm sure there is a performance penalty for such use (Which caused the performance problem).

    Why can't it be simple as myRectangle.X = value.

     

    That is why Every simple action I'm looking for require hours of searching

     

    What were those WPF folks thinking?

    We tried to balance extensibility and usability in WPF.  There are new concepts, we hope to make them easy to learn and make sense once you learn them.

     

    Reason for Attached properties:

    When dealing with out Layout system, we want to provide the ability for anybody to build new Panels.  Inside of those panels you should be able to put normal elements:

     

    <my:RobPanel>

       <Button />

       <Button />

    </my:RobPanel>

     

    Often, the new panel will need to define a property that the user can place on the children of that panel to control how the panel arranges the children.

     

    <my:RobPanel>

       <Button RotationsPerMinute="60" />

       <Button RotationsPerMinute="3" />

    </my:RobPanel>

    Unfortunately that won't work.  RotationsPerMinute is a newly invented property.  The Button class shipped before the RobPanel was ever built and the Button class designers forgot to include this important property!

     

    So WPF has the concept of attached properties.  One class defines the property.  You attach it to instances of other objects.

    <my:RobPanel>

       <Button Name="b1" my:RobPanel.RotationsPerMinute="60" />

       <Button Name="b2" my:RobPanel.RotationsPerMinute="3" />

    </my:RobPanel>

     

    The challenge is how can you expose this to developers now.

    RobPanel.SetRotatationsPerMinute(b1, 30);

     

    int currentRotationsPerMinute = RobPanel.GetRotationsPerMinute(b1);

     

    So if you buy the need for this extensibility, then you need to ask why is Canvas.Top and Canvas.Left modeled as an attached property, but Height and Width are modeled as normal properties.

    Top and Left are modeled as attached properties because they are only respected inside of a Canvas.  If I set Top or Left on a Button inside a StackPanel or DockPanel, it would have no effect.

     

    Object Model should Function

    We feel it is very bad form to have a number of methods or propeties on an object that actually don't do anything.

    My work with DHTML + CSS left me frustrated.  I could set any of the ~200 (?) style properties on any element.  Unfortunately I could never tell if it was supposed to work or not.

     

    Performance Penalty

    Jaffi asked if the static method syntax was a performance problem.

    There is cost, but marginal cost between a Top property defined on an element and an attached property Top defined on the panel.

     

    In WPF, regardless of attached vs. normal, most properties need some special capabilities: databinding, setting via style, animation, etc.

    The property system that enables this is something that is perf critical.  That is probably why we have reimplemented it 3-4 times during our development.

     

    Other Links

    A few more places to go learn about Attached Properties:

    PostTypeIcon
    58,904 Views
  • XAML Markup Extensions

    Filed under: ,

    Markup Extensions are documented in the Windows SDK here.

    In addition to what that document says, you can also use Markup Extensions as elements.  Not just in attributes.

    Somebody asked a question if you could have a tag map to an interface...the answer is no.  But you can have a tag map to a markup extension and do what ever you want in there.  This is a quick example of that.

    I've built a sample MarkupExtension called ClassFactory and added it my small set of downloadable samples.

    Here is a picture of this demo:

     

    XAML\MEasOE.xaml

    ...
        <Button>
          <RadioButton>test button</RadioButton>
        </Button>
        <Button>
          <Button.Content>
            <!-- Button.Content should not be necessary, but a bug requires it in this build-->
            <my:ClassFactory Type="RadioButton">
              <my:ClassFactory.Properties>
                <my:NameValuePair Name="Content" Value="Test button 2" />
              </my:ClassFactory.Properties>
            </my:ClassFactory>
          </Button.Content>
        </Button>
    ...

    ClassFactory.cs

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Serialization;
    using System.Reflection;

    namespace WpfDemos.XAML
    {
        public class ClassFactory : MarkupExtension
        {
            public ClassFactory()
            {
            }
            private Type _Type;
            public Type Type
            {
                get { return _Type; }
                set { _Type = value; }
            }
            private List<NameValuePair> _Properties;
            public List<NameValuePair> Properties
            {
                get
                {
                    if (_Properties == null)
                        _Properties = new List<NameValuePair>();
                    return _Properties;
                }
            }

            //Provide value is called and the return value is used by
            //the XamlReader instead of the MarkupExtension.
            //This could be used to do additional work that normal XamlReading rules don't
            //support.
            public override object ProvideValue(object targetObject, object targetProperty)
            {
                object o =  Type.Assembly.CreateInstance(Type.FullName);
                foreach (NameValuePair prop in Properties)
                {
                    PropertyInfo pi = Type.GetProperty(prop.Name);
                    //This would need to add typeconverter support to set types that aren't
                    //assignable by strings.
                    pi.SetValue(o, prop.Value, null);
                }
                return o;
            }

        }
    }

    PostTypeIcon
    20,308 Views
  • Jan'06 CTP WPF Tech Demos

    Filed under: ,

    I just posted a set of 5 wpf technology demos that work on the January 2006 CTP showing:

    http://robrelyea.com/demos/wpfDemoShell 

    Contains working versions of the following demos:

    • Data Visualization (Auction items)
    • Flow Document
    • Layout (basic panels, layout-to-layout animation)
    • XAML (using a custom class)

    Let me know what you like and what other demos you'd like to see...

    -Rob

    PostTypeIcon
    5,976 Views
  • New designer tool 1st CTP (Expression Interactive Designer)

    Filed under:

    At the PDC, developers could try it out in the hands on labs.  On Channel 9 last year, you could see demos.  Now, you can download its first CTP (Customer Tech Preview) and check out a new Channel 9 video.

    I'm fantastically excited to see the first CTP of Expression Interactive Designer, "Sparkle", being posted!

    Check out 5 short videos (10 minutes total) that show off what it (and WPF) can do:
       http://www.microsoft.com/products/expression/en/demos.mspx?v=id_design

    What do you think?

    :-)

    PostTypeIcon
    3,305 Views
  • Busy week...transitioning from xaml to tools...talks, etc...

    Filed under:

    I've had 2 presentations this week and 1 ask the experts session with the Microsoft field (Technical Specialists, Developer Evangelists, Consultants, etc...).  I really enjoy meeting with customers or other microsoft folks.

    I used to be part of the Microsoft Field...for 5 years in our Chicago office.  Loved the job.  So I find it especially fun to present to the field.

    My big challenge this week is that now that we have tools coming out (Visual Studio "Orcas" December 2005 CTP - with "Cider" and Microsoft Expression Interactive Designer (coming soon)) I find myself having to change my presentation style and content.  No longer can I sit in XAML and C# or XAML and VB.  I love that I can make this transition, but it will take a few times to figure out how to best weave in tools with wpf details, etc...

    I helped drive and do another big checkin that got in successfully today.  If things go well tomorrow, we'll have that change in a CTP in a month or two.

    Mapping PIs are dead.  :-)

    PostTypeIcon
    3,487 Views
  • IAddChild says bye-bye

    Filed under: ,

    We hit the deadline for DCR (Design Change Requests) for WPF this month.

    I rolled up my sleeves a bit to help the development team do some additional changes.  We just stopped the XamlReader (formerly Parser) from calling IAddChild.  You should start using the ContentPropertyAttribute in place of IAddChild...I'll post more details when that build becomes public...

    Have a great holiday season.  I'm staying in town...relaxing a bit...working a bit.  You can get so much done when no meetings are happening!

     

    PostTypeIcon
    14,469 Views
  • Top 10 things about WPF

    Filed under:

    Chris and Ian wrote a piece for MSDN:

       Top Ten UI Development Breakthroughs In Windows Presentation Foundation

    Good reading.

     

    Thoughts?

    PostTypeIcon
    2,591 Views
  • IronPython and WPF

    Filed under:

    Glad to find a nice link to a great demo of IronPython from Jim Hugunin.

    In version 1 of WPF, we chose to not enable scripting scenarios, but instead require you to compile any code.  At least that is what we thought...the demo shows:

    "interactive exploration and GUI building from a command prompt as well as simple embedding as a scripting language in an existing Windows Presentation Foundation application."

    It even shows loading some UI using XAML from IronPython code.

    Love it!

    -Rob

    PostTypeIcon
    4,496 Views
  • Does WPF focus too much on markup scenarios?

    Filed under: ,

    Charles Petzold asks if we are deliberately or accidentally making code-based scenarios difficult.  He sums it up well with the title of the piece: "XAML Rules (but Code Suffers)".

    Thanks Charles for raising this issue.  I'll make sure the right dev team sees the feedback.

     

    Please let us know other scenarios that are difficult from code.  We haven't found them all, but want to hear...many of these decisions are not deliberate.


    We still have some constructs that the XAML parser uses that don't help us make sure we build well designed objects.

    As I said back in October 2004:

    For a long time, we've relied on IAddChild and let component authors decide what their ContentProperty was.  We're hoping to decorate types with that information and remove IAddChild from Avalon.

    We are now finally in the middle of trying to do that change.  We are making the parser stop calling IAddChild.  An example of fixes that we need to do to help make this possible:

    1. Make Grid stop supporting RowDefinition/ColumnDefinition as direct children of Grid.
    2. Make sure we decorate the appropriate ContentPropertyAttribute for all classes.  For example, Panel will have [ContentProperty("Children")]
    3. Make sure collections support IList.  For example, UIElementCollection will get an IList mechanism.

    So instead of having IAddChild implemented on Panel, we added the ContentProperty attribute to that class.  We then make sure the collection that is returned by that property supports IList.

    We are finding and fixing a bunch of issues including incompletely designed classes where problems where hidden by the reliance on IAddChild...

    In the public builds you may not be able to wean yourself from IAddChild yet...perhaps due to blocking bugs...but you should try.  I'll eventually publish more details in this area...let me know if you are blocked by any lack of info here...

    PostTypeIcon
    12,848 Views
  • November 2005 CTP of WinFX is released. Works on Final .Net Framework 2.0 and with Final VS 2005!

    Filed under:

    The much anticipated release of our November 2005 CTP of WinFX is here.
    See Tom Archer's announcement with pointers to the installs.
    Karsten also posts some good information about the release.

    This is the last time you'll need to uninstall/clean your machine of  .Net Framework 2.0 and VS 2005 betas.

    Woo Hoo!

    PostTypeIcon
    3,929 Views
  • WPF and Rich Content Model

    Filed under:

    Doing my feedster search for WPF, I found a post where Aaron was excited about embedding a combo box inside a textbox.  He has a picture of it in action.

    One key developer benefit of WPF is that you can easily embed almost any control inside of another.  Checkbox inside of a Menu, yep.  ComboBox inside of a RichTextBox, yep.  etc...

    How substantial a capability is this for you?  What scenarios does it enable that you are excited about?

     

     

    (I'm trying a new setting for this post...syndicating an excerpt...)

    PostTypeIcon
    4,145 Views
  • Databinding + Datavisualization Demo with WPF/XAML/VB

    Filed under: , ,

    Many people say that Databinding is one of the more impactful of the features in WPF.
    Namita wrote a great set of demos for her PDC talk about Databinding with WPF.

    As part of a few talks (some VB customers, a Vista + WPF talk, a talk at the Borland Developer Conference), I used that demo.

    I've finally gotten around to posting my version of it.

    Here is a screen shot of the auction window:

    If you click on the Map button in bottom left of that, a nice data visualization example is shown using a custom tree map control that I believe Kevin Moore wrote:

     

    The app has a good separation between the data and the UI...

    The items on the left of the auction window are just renderings for each AuctionItem in a listbox.

    From Window1.xaml:

    <ListBox ItemsSource="{Binding Path=.}"
         LayoutTransform="scale .7 .7"
         Grid.Column="0"
         Name="itemDisplay"
         />

    The rendering for each auction item is controlled by a data template that was specified in myapp.xaml declaratively.

    <DataTemplate DataType="{x:Type local:AuctionItem}" >
       <Viewbox>
        <Grid  Margin="0" Width="250" Height="200">
         <Grid.LayoutTransform>
          <ScaleTransform ScaleX="1.5" ScaleY="1.5"/>
         </Grid.LayoutTransform>
         <!-- image element -->
         <Ellipse
          Width="200"
          HorizontalAlignment="Right"
             Margin="10"
             >
          <Ellipse.Fill>
           <Binding Path="RemainingSeconds">
            <Binding.Converter>
             <local:ColorDateConverter/>
            </Binding.Converter>
           </Binding>
          </Ellipse.Fill>
         </Ellipse>
         
         <Border HorizontalAlignment="Center" VerticalAlignment="Center"             
          Padding="4" Margin="30" BorderBrush="#D2CFCF"
          BorderThickness="1" Background="White">
          <Image>
           <Image.Source>
            <Binding Path="Image"/>
           </Image.Source>

          </Image>
         </Border>


         <Viewbox Height="80" Width="80" Margin="10"
            HorizontalAlignment="Right"
            VerticalAlignment="Center"
            >
          <!-- clock background -->
          <Grid>
           <Ellipse Width="100" Height="100" Margin="4"
            HorizontalAlignment="right"
            VerticalAlignment="bottom">
            <Ellipse.Fill>
             <Binding Path="RemainingSeconds">
              <Binding.Converter>
               <local:ColorDateConverter/>
              </Binding.Converter>
             </Binding>
            </Ellipse.Fill>
           </Ellipse>

     


           <!-- time remaining Days text -->

           <TextBlock
            FontSize="40px"
            TextAlignment="Center"
            Width="100"
            HorizontalAlignment="right"
            FontFamily="Segoe"
            Foreground="#5B5C59"  
            VerticalAlignment="Bottom"
            Height="80" 
            Text="{Binding Path=RemainingSeconds}"/>


           <TextBlock FontSize="10px" Foreground="#AAFFFFFF" Height="36"
            HorizontalAlignment="right" FontFamily="Segoe"
            VerticalAlignment="Bottom"
             TextAlignment="Center" Width="100"   Text="SECONDS" />

     

           <!-- hour hand -->
           <Canvas  HorizontalAlignment="Right"
            VerticalAlignment="Bottom" Height="100" Width="100">


            <Line StrokeThickness="3pt"  Stroke="#6FFFFFFF"
           X1="50" Y1="50" >
             <Line.Y2>
              <MultiBinding>
               <MultiBinding.Converter>
                <local:PosYConverter/>
               </MultiBinding.Converter>
               <Binding Path="RemainingSeconds"/>
               <Binding Path="StartDate"/>
              </MultiBinding>
             </Line.Y2>
             <Line.X2>
              <MultiBinding>
               <MultiBinding.Converter>
                <local:PosXConverter/>
               </MultiBinding.Converter>
               <Binding Path="RemainingSeconds"/>
               <Binding Path="StartDate"/>
              </MultiBinding>
             </Line.X2>
            </Line>

            <Ellipse Width="10" Height="10"
                Canvas.Top="45" Canvas.Left="45"
                Fill="#6FFFFFFF" />


           </Canvas>

     

           <!-- Clock chrome -->

           <Ellipse Width="100" Height="100" HorizontalAlignment="right" Margin="4"
            VerticalAlignment="bottom"
            RenderTransform="scale 1 -1 translate 0 57" >
            <Ellipse.Fill>
             <RadialGradientBrush Center="0.5,0.1" RadiusX="1.5" >
              <RadialGradientBrush.GradientStops>
               <GradientStopCollection>
                <GradientStop Offset="0" Color="#AAFFFFFF" />
                <GradientStop Offset="0.18" Color="Transparent" />
               </GradientStopCollection>
              </RadialGradientBrush.GradientStops>
             </RadialGradientBrush>
            </Ellipse.Fill>
           </Ellipse>

           <Ellipse Width="100" Height="100"
            HorizontalAlignment="right"  Margin="4"
            VerticalAlignment="bottom" RenderTransform="scale 1 -1 translate 0 120" >
            <Ellipse.Fill>
             <RadialGradientBrush Center="0.5,0.2" RadiusX="1.2" >
              <RadialGradientBrush.GradientStops>
               <GradientStopCollection>
                <GradientStop Offset="0" Color="#66FFFFFF" />
                <GradientStop Offset="0.35" Color="Transparent" />
               </GradientStopCollection>
              </RadialGradientBrush.GradientStops>
             </RadialGradientBrush>
            </Ellipse.Fill>
           </Ellipse>
           <Ellipse Width="100" Height="100"
            HorizontalAlignment="right"
            VerticalAlignment="bottom"  Margin="4"
            Stroke="VerticalGradient #66FFFFFF #44FFFFFF" StrokeThickness="1.5" />
           <Ellipse Width="102" Height="102"
            HorizontalAlignment="Right"
            VerticalAlignment="Bottom"  Margin="4"
            Stroke="VerticalGradient #11000000 #33000000"  StrokeThickness="1.5"  RenderTransform="translate 1 1" />
          </Grid>
         </Viewbox>


         </Grid>
       </Viewbox>
      </DataTemplate>

    Dig into the demo and go watch Namita's pdc talk!

    Please let us know what you think.

    PostTypeIcon
    24,325 Views
< Previous 1 2 3 4 5 Next > ... Last »