January, 2008

  • Cloudy in Seattle

    Actipro WPF Studio - Updated with Improved Design Time Support

    • 0 Comments

    On 1/29/2008, Actipro released a new build of their WPF Studio.  You'll recall that I blogged about their use of extensibility to improve the design time interaction of their controls.  This new release ups the ante with drag and drop layout, a really cool image picker and a host of other improvements across their task panes.

    Check out: http://www.actiprosoftware.com/Products/DotNet/WPF/Ribbon/DesignerSupport.aspx

    Here's a shot of the image picker:

    For a hint on how they did this, here is a tip from resident Cider Architect Brian Pepin:

    There is a service called ExternalResourceService that is defined in Microsoft.Windows.Design.Markup.  It allows you to enumerate the images (and other resources) in the project.  When you find an image you want, it is returned as a type called BinaryResource.  BinaryResource can be used to obtain a stream and it can also be used to obtain a special kind of URI called a "stream" URI.  If you pass this URI to a WPF API that uses URIs, or if you pass it to WebRequest.Create, you can get back a stream as well. 

    This is how we handle all resources in the designer and it allows you to ignore the details of the URI.

    I also updated the screen shots on the previous post referenced above.

  • Cloudy in Seattle

    Mincom Case Study

    • 1 Comments

    Here is a case study of one of the companies we've been working with, Mincom. 

    http://www.microsoft.com/casestudies/casestudy.aspx?casestudyid=4000001266

    They've made great use of Visual Studio 2008 and specifically of Cider/WPF.

  • Cloudy in Seattle

    Showing Attached Properties in the Cider WPF Designer

    • 2 Comments

    If you create a type that defines an attached property, you will notice that this attached property does not show up in the WPF Designer (Cider) Property Browser.  So how do you get it to show up and what level of control do you have over when it shows up?

    As it turns out, you can use the following attributes to control how your properties show up in the Property Browser:

    AttachedPropertyBrowsableWhenAttributePresentAttribute
    AttachedPropertyBrowsableForChildrenAttribute
    AttachedPropertyBrowsableForTypeAttribute

    You apply them to the get accessor of your attached property definition, like this:

        public class WhenAttributePresentTestControl : Grid
        {
            public static readonly DependencyProperty ShowWhenCustomAttributePresentProperty = DependencyProperty.RegisterAttached(
              "ShowWhenCustomAttributePresent",
              typeof(int),
              typeof(WhenAttributePresentTestControl));

            public static void SetShowWhenCustomAttributePresent(UIElement element, int value)
            {
                element.SetValue(ShowWhenCustomAttributePresentProperty, value);
            }

            [AttachedPropertyBrowsableWhenAttributePresentAttribute(typeof(MyCustomAttribute))]
            public static int GetShowWhenCustomAttributePresent(UIElement element)
            {
                return (int)element.GetValue(ShowWhenCustomAttributePresentProperty);
            }
        }

    One thing to keep in mind is that one of the requirements of showing attached properties in the designer is that the owning type needs to have been loaded by the designer.  This happens whenever the designer accesses the type because it is in the XAML source or is a dependency of an element loaded from the XAML source.

    Attached to this post is an example of using all 3 of these attributes.

    AttachedPropertyBrowsableWhenAttributePresentAttribute

    This attribute allows you to specify that your attached property show up in the Property Browser when the selected item has a given attribute applied to it.  If the attribute has a default value, that value also has to be different from the default value.

    In the example above that passes in "MyCustomAttribute" as the attribute to look for, when CustomLabel below is selected in the designer, the Property Browser will show the ShowWhenCustomAttribute attached property however it will not when CustomLabelNoCustomAttribute is selected:

        [MyCustomAttribute]
        public class CustomLabel : Label
        {
        }

        public class CustomLabelNoCustomAttribute : Label
        {
        }

    AttachedPropertyBrowsableForChildrenAttribute

    This attribute indicates that the attached property should be available for the children of the given control.  There are two main flavors for this attribute.  One that includes descendants and one that does not. As you might expect including descendants refers to including all children or simply the direct children of the control.

            [AttachedPropertyBrowsableForChildrenAttribute(IncludeDescendants=true)]
            public static int GetShowForChildrenDeep(UIElement element)
            {
                return (int)element.GetValue(ShowForChildrenDeepProperty);
            }

    AttachedPropertyBrowsableForType

    This attribute allows you to specify that your attached property show up when a given type or types derived from that type are selected in the designer.  The following sample would make your attached property show up when any Grid, derived Grid, Button or derived Button is selected.

            [AttachedPropertyBrowsableForType(typeof(Grid))]
            [AttachedPropertyBrowsableForType(typeof(Button))]
            public static int GetShowForTypes(UIElement element)
            {
                return (int)element.GetValue(ShowForTypesProperty);
            }

    Sample Attached

    I have attached a sample to this blog post the shows the usage of all the attributes listed above in the Cider WPF Designer.

     

  • Cloudy in Seattle

    DevComponents DotNetBar Suite for WPF

    • 3 Comments

    DevComponents recently released their DotNetBar Suite for WPF and it is loaded with design time features.  Using Cider Extensibility, DevComponents really has put together one of the richest design times I've seen to date.

    Denis talks about the features on this blog post.

    The DotNetBar suite provides a set of controls that make it easy to build an application with an Office Ribbon, Window Management and an Outlook style Navigation Pane control. 

    The first thing to notice is that for the elements you care to move to other positions -- the buttons in the Ribbon (including on the application menu), and the windows in the application -- can be moved by simply clicking and dragging.  Very cool use of setting up a ParentAdapter correctly.

    Here's a sequence where I moved a button from the Recent Documents list to the Command Button area to the Application Menu main buttons to a location on the ribbon -- all using drag drop.

    For redocking the windows at design time, the user gets the Visual Studio-esque docking targets and highlighting:

    Much better than having to find the right set of XAML to modify right?

    Each selectable element also has a popup menu associated with it that allows the user to edit the controls in place.

    The application Menu:

    Drop down buttons (these can be dragged dropped around the whole UI to multiple drop targets):

    The Ribbon Tab:

     

    And Windows:

     

    DevComponents have made use of the following Cider Extensibility features to make this happen: Adorners, DefaultInitializers (to setup the XAML for their controls when they are created from the toolbox), and ParentAdapter (for drag/drop move/repositioning of theirr controls).

    Really is a great example of how powerful the Adorner Extensibility features are in Cider.

    Again -- I am looking for more design time examples to feature on this blog so please contact me with your examples!

  • Cloudy in Seattle

    Workaround for Style.Triggers Design Time Issue

    • 3 Comments

    I've received two bug reports from Control Vendors regarding Style.Triggers not working correctly at design time in the WPF Designer RTM.  Fortunately, we do have a workaround to the problem.  Suppose you have a trigger defined as follows:

         <Style TargetType="{x:Type local:CustomControl1}">
            <Style.Triggers>
                <Trigger Property="local:CustomControl1.SecondTemplate" Value="True">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type local:CustomControl1}">
                                <Border Background="Red"
                                BorderBrush="Green"
                                BorderThickness="4">
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </Style.Triggers>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:CustomControl1}">
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}">
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

     What you would expect is that in the designer when you set the SecondTemplate property to true you would get something that looks like this:

    Unfortunately, the style doesn't update.

    To work around this issue, if you define triggers for both the true and false values, you will get the desired behavior:

       <Style TargetType="{x:Type local:CustomControl1}">
            <Style.Triggers>
                <Trigger Property="local:CustomControl1.SecondTemplate" Value="True">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type local:CustomControl1}">
                                <Border Background="Red"
                                BorderBrush="Green"
                                BorderThickness="4">
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Trigger>
                <Trigger Property="local:CustomControl1.SecondTemplate" Value="false">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type local:CustomControl1}">
                                <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}">
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </Style.Triggers>
        </Style>

    Hope that helps!

    This sample is attached.  When you open the sample it will be in a state where the style triggers don't, well, trigger at design time.  If you uncomment the workaround and comment the original style, you will see the style triggers will then work in the designer.

  • Cloudy in Seattle

    Pistachio - “WPF Resource Visualizer”

    • 1 Comments

    There are definitely some cool 3rd party WPF tools coming out as of late -- for example, Mole.  Here is another cool one that helps you to get a handle on your WPF resources.

    http://www.granthinkson.com/2007/11/08/announcing-pistachio-wpf-resource-visualizer/

Page 1 of 1 (6 items)