Welcome to MSDN Blogs Sign in | Join | Help

WPF Designer: Changes and Fixes in VS2008 SP1 Beta

Here's the definitive list:

List of changes and fixed issues for Visual Studio 2008 Service Pack 1 Beta for Windows Presentation Foundation Designer

New features

  • The Properties window now contains the Events tab. The Events tab lets you create events, assign events, and review events.
  • The Properties window now includes a category sort option and an alphabetical sort option to allow for faster property location.
  • Code changes have been made to the XAML Refactor/Rename definition and to the Go to definition. These changes allow XAML rename operations to occur automatically. Additionally, you can navigate the XAML definition by pressing F12.
  • You can now drag controls or create controls from the toolbox in XAML view or in Design view. You can do this even if you use a split view configuration.
  • Snaplines are now implemented for control margins. This lets the designer control a fixed distance from other controls, from container edges, or from gridlines.
  • Tab controls now support TabItem activation and TabItem design. To do this, click the tab that you want to design.
  • The Expander control now expands conditionally based on what is selected. You can design the contents of the Expander control at design time with affecting the IsExpanded attribute of the runtime.
  • Many stability improvements have been added to Visual Studio 2008 SP1. These include improvements to document loading in the designer and to error reporting. Because of these improvements, you will be able to load more documents in the designer.
Posted by wcsdkteam | 3 Comments

Download Visual Studio 2008 SP1 Beta

Get it here.

Discuss amongst yourselves at the forum.

Don't miss Guy Burstein's guided tour.

Here's the official word:

Visual Studio 2008

  • With Visual Studio 2008, developers and development organizations have the tools that enable them to be more productive, take advantage of all the latest platform advances on Windows, Office and the Web, and collaborate more effectively throughout the software lifecycle.
  • Visual Studio 2008 offers more than 250 new features and improvements to existing features, providing developers of all skills sets – from the hobbyist to the small development shop to enterprise development organizations – the tools they need to build great applications.
  • Microsoft is committed to helping developers be successful and provides community resources, reference material, software, add-ins, and more to guide construction of Software+Services applications, data-driven solutions, and compelling user experiences.
  • Visual Studio 2008 SP1 beta introduces improvements and new functionality in several areas including:
    • Full support for SQL Server 2008.
    • Improved functionality and performance in the WPF designers.
    • Additional components and tools for Visual Basic & Visual C++ including an MFC-based Office 2007 Ribbon and various stability improvements.
    • Richer JavaScript features.
    • Improved Web development and site deployment.
    • Performance improvements for the IDE.
    • Improvements to TFS to respond to customer feedback on version control usability and performance, improved email integration with work item tracking.  In addition, TFS now provides full support for hosting on SQL 2008 and Windows Server 2008.

.NET Framework 3.5

  • With the .NET Framework 3.5 Microsoft is extending the capabilities in the framework with new support for Internet protocols, peer-to-peer communication, device programmability, and data handling. The .NET Framework provides a single, common programming model supporting the broadest set of applications.
  • Microsoft is committed to delivering enhanced capabilities and increased productivity for developers in the .NET Framework 3.5.
  • Expanded and improved offerings in the .NET Framework and tooling support in Visual Studio 2008 gives developers enhanced capabilities to build S+S, SOA and Web 2.0 applications.
  • The .NET Framework 3.5 SP1 beta introduces improvements and new functionality in several areas including:
    • More controls, streamlined setup, improved start-up performance, powerful new graphics features for client development and rich data scaffolding, and improved AJAX support.
    • Introduces the ADO.NET Entity Framework and ADO.NET Data Services, simplifying data access code in applications by providing an extensible, conceptual model for data from any data source and enabling this model to closely reflect business requirements.

ItemControls don’t properly select items or raise events when bound to a data source

About a month ago, I saw two unrelated questions where an ItemsControl was not behaving correctly when clicking on an item: Events weren’t being raised, items weren’t getting selected; chaos ensued.  In both cases, the developer was adding an items container to the data template.  (As a refresher, ListBoxItem, ListViewItem, and TreeViewItem are examples of item containers.)  They were doing something like the following:

 

        <Grid>

            <Grid.Resources>

                <src:ItemsForSale x:Key="Data"/>

            </Grid.Resources>

            <ListBox ItemsSource="{StaticResource Data}">

                <ListBox.ItemTemplate>

                  <DataTemplate>

                        <ListBoxItem Padding="3,8,3,8" MouseDoubleClick="ListBoxItem_MouseDoubleClick" >

                            <TextBlock Text="{Binding Path=Description}"/>

                        </ListBoxItem>

                    </DataTemplate>

 

                </ListBox.ItemTemplate>

 

            </ListBox>

        </Grid>

 

When the correct way to implement the ListBox is something like the following:

 

        <Grid>

            <Grid.Resources>

                <src:ItemsForSale x:Key="Data"/>

            </Grid.Resources>

            <ListBox ItemsSource="{StaticResource Data}">

                <ListBox.ItemContainerStyle>

                    <Style  TargetType="ListBoxItem">

                        <Setter Property="Padding" Value="3,8,3,8"/>

                        <EventSetter Event="MouseDoubleClick" Handler="ListBoxItem_MouseDoubleClick"/>

                    </Style>

                </ListBox.ItemContainerStyle>

                <ListBox.ItemTemplate>

                    <DataTemplate>

                        <TextBlock Text="{Binding Path=Description}"/>

                    </DataTemplate>

 

                </ListBox.ItemTemplate>

 

            </ListBox>

        </Grid>

 

In the second example, properties and events for item containers are set on a style, and the data template contains only elements that go in each item container.  You see, when the ItemsControl is bound to a data source, an items container is implicitly created for each item in the source, so in the first example above two ListBoxItem objects are made for each item: the one that is implicitly created and the one in the data template. In the second example, only the implicitly created ListBoxItem is present, and the Padding and event handler from the style is applied to each ListBoxItem.

 

For full disclosure, I must say that when I experimented with the first example, I got inconsistent results.  Sometimes I couldn’t select an item but I could get the double click event to occur and sometimes I could select the item but not raise the event.  So be forewarned: Don’t put item containers in data templates; only weird things happen if you do!

 

Posted by wcsdkteam | 0 Comments

Databinding and Add-Ins

There are many advantages to using the .NET Framework add-in technology to factor application logic and UI, including security isolation, discovery, activation, communication, lifetime management, and versioning.

WPF builds on the .NET Framework add-in technology to enable visual add-ins ie add-ins that provide UI for host applications to display. All that you need to do is define the contract to specify what types of things the host wants the add-in's UI to do. The end result for the user is that they see both host and add-in UI intermingled without knowing about the complex machinery underneath to make it work.

And, to some degree, developers might approach the development of add-ins the same way. For example, when a WPF host application displays a UI provided by an add-in, developers might intuitively expect features like data binding, commanding etc to just work. Features like this, though, need a little extra work to, err, get working because features like these weren't originally designed to work across the isolation boundary between host and add which is the space between the host's application domain and the add-ins application domain. (This use of application domains enables security isolation.)

The attached sample demonstrates how to implement host/add-in applications to support data binding. Specifically, the sample shows a host application that manages a data object (Person) and provides it to UI add-ins that either re-visualize the data or allow editing of the data, or both. Here's how the application looks at run time.

To understand the sample, you'll need to be familiar with .NET Framework and WPF add-in support. This SDK document provides a good starting point.

You'll need to play with the sample to see how it really works but the 10000' view is:

  • There is one contract for the Add-In
  • There is one contract for the Person data object
  • The host instantiates the Person data object and binds some UI to it.
  • The host activates and displays a UI provided by the add-in, to which the host passes the Person object. The add-in UI also binds to the Person object.
  • When the host UI that is bound to the data object is updated, the changes are communicated to the add-in UIs that are also bound to the data object.
  • When the editable add-in UI that is bound to the Person data object is updated, the changes are communicated back to the host.

To the host and add-in UIs, all they see is a Person data object that implements INotifyPropertyChanged which is the data binding interface that essentially ensures bound UI are updated when the data objects they are bound to are updated. The add-in pipeline to make this work is a little more involved, technically, but is the same as using INotifyPropertyChanged, in concept.

You'll find the best way to grok the sample is to download it and see it running.

Enjoy!

Posted by wcsdkteam | 0 Comments
Filed under: ,

Attachment(s): WPFAddInDataBindingSample.zip

A Sample and a Question

This month, I’m asking for your input to this question: Which type of sample do you prefer, simple and straightforward, or complex with a more real-world scenario?  We often hear that our customers want real-world examples, and I’d like to understand at what level they want the code to be “real-world?”

 

I recently wrote a topic describing how to create a TreeView with an unknown depth, and I used very simple code to illustrate the concept.  Here’s the interesting parts of the topic:

 

Bind a TreeView to Data that has an Unknown Depth

 

There might be times when you want to bind a TreeView to a data source whose depth is not known. This can occur when the data is recursive in nature, such as a file system, where folders can contain folders, or a company's organizational structure, where employees have other employees as direct reports.

 

The data source must have a hierarchical object model. For example, an Employee class might contain a collection of Employee objects that are the direct reports of an employee. If the data is represented in a way that is not hierarchical, you must build a hierarchical representation of the data.

 

When you set the ItemsControl.ItemTemplate property and if the ItemsControl generates an ItemsControl for each child item, then the child ItemsControl uses the same ItemTemplate as the parent. For example, if you set the ItemTemplate property on a data-bound TreeView, each TreeViewItem that is generated uses the DataTemplate that was assigned to the ItemTemplate property of the TreeView.

 

The HierarchicalDataTemplate enables you to specify the ItemsSource for a TreeViewItem, or any HeaderedItemsControl, on the data template. When you set the HierarchicalDataTemplate.ItemsSource property, that value is used when the HierarchicalDataTemplate is applied. By using a HierarchicalDataTemplate, you can recursively set the ItemsSource for each TreeViewItem in the TreeView.

 

<Page

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Page.Resources>

    <XmlDataProvider x:Key="myCompany" XPath="Company/Employee">

      <x:XData>

        <Company xmlns="">

          <Employee Name="Don Hall">

            <Employee Name="Alice Ciccu">

              <Employee Name="David Pelton">

                <Employee Name="Vivian Atlas"/>

              </Employee>

              <Employee Name="Jeff Price"/>

              <Employee Name="Andy Jacobs"/>

            </Employee>

            <Employee Name="Bill Malone">

              <Employee Name="Maurice Taylor"/>

              <Employee Name="Sunil Uppal"/>

              <Employee Name="Qiang Wang"/>

            </Employee>

          </Employee>

        </Company>

      </x:XData>

    </XmlDataProvider>

 

    <!-- Bind the HierarchicalDataTemplate.ItemSource property to the employees under

         each Employee element. -->

    <HierarchicalDataTemplate x:Key="EmployeeTemplate"

                              ItemsSource="{Binding XPath=Employee}">

      <TextBlock Text="{Binding XPath=@Name}" ></TextBlock>

    </HierarchicalDataTemplate>

 

    <Style TargetType="TreeViewItem">

      <Setter Property="IsExpanded" Value="True"/>

    </Style>

  </Page.Resources>

 

  <Grid>

    <TreeView ItemsSource="{Binding Source={StaticResource myCompany}}"

              ItemTemplate="{StaticResource EmployeeTemplate}"/>

  </Grid>

</Page>

 

I think this nicely illustrates the concept, but you can hardly call it a real-world example.  A more real-world example is creating a TreeView that mirrors the file structure of a Disk Drive.  Kevin Moore’s Bag-O-Tricks included such a control, and we certainly could include a sample that does the same, but such a sample will be more complex than just showing how to make the TreeView recurse an unknown level. If I used Kevin Moore’s code, I couldn’t even show the entire XAML.  The most that would make sense to show is HierarchicalDataTemplate, and then refer people to the sample for the entire sample.

 

    <HierarchicalDataTemplate x:Key="DirectoryStyleForTreeView"

                  DataType = "{x:Type fp:SelectableDirectory}"

                  ItemsSource = "{Binding Path=SubDirectories}">

      <StackPanel Orientation="Horizontal">

        <CheckBox Name="checkBox" IsChecked="{Binding Path=IsSelected}" Focusable="false">

          <DockPanel x:Name="panel">

            <Control x:Name="icon" Template="{StaticResource folder}"/>

            <TextBlock Text="{Binding Path=Name}" Margin="0 1.5 0 0"/>

          </DockPanel>

        </CheckBox>

      </StackPanel>

    </HierarchicalDataTemplate>

 

 

I’ve attached the sample, so you can look at the entire application and see the HierarchicalDataTemplate in context of the program. 

 

I’ve attached both samples for you to compare the complexity versus the real-world use value.  My thought is the Folder Picker sample is a lot less self-contained and takes a lot more time to investigate how to populate a TreeView for an unknown depth, which is why I used the simpler sample to explain this concept.  My question is which one do you prefer?  I know your immediate reaction might be to say, “Hey, why don’t you give us both?”  That’s definitely ideal, but for the sake of argument, let’s assume only one is allowed.  Is the simpler one adequate, or is it worth your time (and ours) to provide the more complex sample and let you experiment with it to extract the information you need?

 

Posted by wcsdkteam | 7 Comments

Attachment(s): Samples.zip

A sample for the holidays

For my last task of the year, I answered a question about binding a ComboBox to a collection of StrokeCollections that has a custom property to indicate the name of the StrokeCollection.  This was a fun little project so I decided to post it here to share.  My solution was to inherit from StrokeCollection and expose the name as a property.

    public class NamedStrokeCollection : StrokeCollection

    {

        Guid nameGuid = new Guid("12345678-9012-3456-7890-123456789012");

 

        #region constructers that mirror StrokeCollection

        public NamedStrokeCollection()

            : base()

        {

        }

 

        public NamedStrokeCollection(IEnumerable<Stroke> strokes)

            : base(strokes)

        {

        }

 

        public NamedStrokeCollection(System.IO.Stream stream)

            : base(stream)

        {

        }

        #endregion

 

 

        public NamedStrokeCollection(string name)

            : base()

        {

            Name = name;

        }

 

        public NamedStrokeCollection(IEnumerable<Stroke> strokes, string name)

            : base(strokes)

        {

            Name = name;

        }

 

        public NamedStrokeCollection(System.IO.Stream stream, string name)

            : base(stream)

        {

            Name = name;

        }

 

         

        // StrokeCollection doesn't have a constructor that takes an ISF, so

        // since that's the easiest way for *me* to create a stroke collection is to pass in

        // an ISF string, I created a static method to return a NamedStrokeCollection

        // when it's passed in a string.

        static public NamedStrokeCollection GetStrokes(string strokesStr, string name)

        {

            // Create a StrokeCollection the string and add it to

            StrokeCollectionConverter converter =

                new StrokeCollectionConverter();

 

            StrokeCollection strokes = converter.ConvertFrom(strokesStr) as StrokeCollection;

            NamedStrokeCollection namedStrokes = new NamedStrokeCollection(strokes);

            namedStrokes.Name = name;

 

            return namedStrokes;

        }

 

        public string Name

        {

            get

            {

                if (this.ContainsPropertyData(nameGuid))

                {

                    return (string)this.GetPropertyData(nameGuid);

                }

                else

                {

                    return "";

                }

            }

 

            set

            {

                this.AddPropertyData(nameGuid, value);

            }