Today I’m starting off a new topic, called “5 Reasons …”. Five reasons why you need things, why you should do things or not, or why to love things or just hate them. I’ll start this by giving you five reasons why you need an architect in your software development project.
The reasons provided here are inspired by the great article of Daniel Akenine in the Microsoft Architecture Journal No. 15 (Link). The article gives the results of a study from IASA Sweden on the roles of an architect.
1. Architects can handle complexity
I guess everyone is fully aware that software projects got more and more complex over the last years. Today we are building huge software environments that can deal with lots of traffic and data. Why do we do this? Well, because users expect software or a device to deliver some kind of functionality or data just on a fingertip. They want to see personalized data, expect automatic notifications or even advice. They want to access their data everywhere at every time without worrying about network protocols or security. They need intuitive user interfaces, easy access and of course they expect performance. Users are mostly impatient. They don’t want to wait. If you have an application that is slow or ugly, you’re out.
Architects take all these concerns – and even more – into account when planning and designing software systems. They have a birds-eye view on the application landscape and can face the complexity, whether it is fundamental or accidental (see …). The goal of an architect shall be to reduce at least the fundamental complexity as far as possible in order to achieve a manageable, scalable and extendable application design.
2. Architects know patterns
You have heard of patterns? You should! You’re using patterns? You should! Patterns provide proven and well understood solutions to common problems. They make software or its components more understandable and deliver a common grammar for all developers in a team. You can find and use patterns in every phase of a project and on every layer inside your application. There is already a lot of work done on patterns and numerous pattern catalogues exist (e.g. “Design Patterns” by the Gang of Four, Pattern Oriented Software Architecture (POSA Series), Hillside Group). While most software developers know implementation specific patterns, architects are well aware of design and system wide patterns. They know more specialized patterns related to application architecture. Together with these patterns they help plan and build manageable, understandable software systems.
3. Architects plan for non-functional features and think beyond the project
Imagine an application that is beautifully designed in terms of the user interface. It is intuitive, the colors and control elements are well aligned and it just pleases the user’s eye. But all the design gimmicks lead to very bad responsiveness. Opening up a new dialog takes five to eight seconds. One might say, that’s okay, but imagine such software used by an agent in a call center. That would not be acceptable. This is just a very simple example where you see, that there are more concerns to be taken into account when designing software systems: functional and non-functional concerns. Especially non-functional concerns are often not clearly defined or even spoken out in software projects. It’s the task of the architect to plan the overall design regarding to these concerns. Additionally they have to provide a long-term strategy for the solution and its environment. Most business applications are integrated in an existing information infrastructure and are operated at least five years, mostly longer. Architects have to plan their integration and the whole maintenance lifecycle.
4. Architects act as agents between analysts, project managers and developers
Architects play a key role in a software development project. Analysts mostly talk to customers in order to identify their need and requirements. Developers in turn try to interpret these requirements and implement them in form of a feature. Project managers pay attention that features are not beyond the budget. These three roles have different goals and motivations. They even speak different languages. Analysts speak the domain language of the customers. Developers speak a very technical language. A good architect understands and speaks all the needed languages. They can talk with analysts about the requirements and can translate the information to the developers using a more technical language. Architects can talk to the management and understand their needs are possibly reflected by an efficient architecture where features can easily be added.
5. Architects can communicate, present and defend their architecture
When it comes to present or even defend an architecture, architects are some kind of diplomats. They must explain their architecture to the various stakeholders in a project and have to make sure, that everybody involved accepts that architecture and feels comfortable with it. This again means that a good architect is able to present her architecture in an understandable way on every level in a project, from top management down to the developers.
I’m well aware that there are dozens of other good reasons why you should employ an architect, but that five reasons provide the quintessence from my point of view. If you need even more reasons or want to learn more about the role of an architect, read the Architecture Journal, No. 15. You may also visit the IASA Homepage and look for a chapter near you. Additionally there are a lot of related books out there to get you started in the field of software architecture.
Thursday, December 8, 2011
Monday, November 21, 2011
WPF - Working with XML and XmlDataProvider
Working with XML or XML related data is not always easy in C#. With .NET Framework 3.0 Microsoft introduced the XmlDataProvider as part of the data provider infrastructure. Using XmlDataProvider inside WPF applications together with some XPath expressions makes it really easy to bind whatever kind of Xml fragment you have to some user interface controls. This blog entry shows how to use the provider by showing a simple example.
The XML Data
First of all, we need some sample data. I used the data from the XmlDataProvider example at the according MSDN site:
Let’s start by examining the combo box. Its ItemsSource property is bound to the XmlDataProvider. The root node is selected by using an XPath expression. It selects all direct children of the inventory node, which are in that case books and CDs. In order to show some friendly text inside the combo box it defines an ItemTemplate, which has a TextBlock bound to the Name property of the current XmlNode. The XPath expression returns a list of XmlNode objects. Therefore you can bind to any property of that object. You could also bind to another XPath expression based on the current node.
A ListBox shall show all the items of the selected category. The data context of the container containing the list box is bound to the currently selected item of the combo box. That item is an XmlNode object, so the list box can be bound to the nodes ChildNodes collection. You don’t need to specify the Path attribute, but it makes the code more readable. Again we’re defining an ItemTemplate for the list. This time we use an XPath expression to bind to the title node in order to display the inventory item title inside the list. We could have also bound to the InnerText property of the XmlNode. Use whatever you like.
When the user selects an item in the list, its properties shall be shown next to the list and at least the summary shall be editable. The data context of the Grid container element is therefore bound to the selected item of the list box. Inside the Grid are TextBlocks for displaying the ISBN and the summary of the currently selected inventory item. The summary is displayed inside a TextBox so the user may change it. Note, that the ISBN is an attribute of the book node, so you have to use an @ symbol inside the XPath expression.
Changing and Saving Data
XmlDataProvider keeps an XmlDocument with an XmlNode object collection of the xml document in memory. Using the xml API in .NET you can do any modifications you want. What’s cool about using XmlDataProvider in WPF is that when you change the value of a bound XmlNode inside a user control, the new value will be written to the XmlNode object. That means it supports two-way binding. That makes it extremely easy to edit the summary node in our example. In order to save the changes back to the file system, you just need to call the save method of the underlying XmlDocument:
private void OnSaveClicked(object sender, RoutedEventArgs e)
{
Summary
The XmlDataProvider together with WPF binding makes it very easy to access, display, and modify Xml data. You can navigate through the data with just some simple XPath expressions. For small documents it is extremely fast. For larger documents consider loading the document in a background thread and assign it manually to the provider. Always remember that the XmlDataProvider is just a wrapper around an XmlDocument.
The XML Data
First of all, we need some sample data. I used the data from the XmlDataProvider example at the according MSDN site:
<Inventory xmlns="">
<Books>
<Book ISBN="0-7356-0562-9" Stock="in" Number="9">
<Title>XML in Action</Title>
<Summary>XML Web Technology</Summary>
</Book>
<Book ISBN="0-7356-1370-2" Stock="in" Number="8">
<Title>Programming Microsoft Windows With C#</Title>
<Summary>C# Programming using the .NET Framework</Summary>
</Book>
<Book ISBN="0-7356-1288-9" Stock="out" Number="7">
<Title>Inside C#</Title>
<Summary>C# Language Programming</Summary>
</Book>
<Book ISBN="0-7356-1377-X" Stock="in" Number="5">
<Book ISBN="0-7356-1377-X" Stock="in" Number="5">
<Title>Introducing Microsoft .NET</Title>
<Summary>Overview of .NET Technology</Summary>
</Book>
<Book ISBN="0-7356-1448-2" Stock="out" Number="4">
<Title>Microsoft C# Language Specifications</Title>
<Summary>The C# language definition</Summary>
</Book>
</Books>
<CDs>
<CDs>
<CD Stock="in" Number="3">
<Title>Classical Collection</Title>
<Summary>Classical Music</Summary>
</CD>
<CD Stock="out" Number="9">
<Title>Jazz Collection</Title>
<Summary>Jazz Music</Summary>
</CD>
</CDs>
</Inventory>
We have an inventory containing books and CDs. Every book and CD has two child elements: title and summary. Books got an additional attribute for their ISBN number. The data is stored in a separate XML file.
The View
We will create a very simple WPF view for displaying our data. It will contain a combo box in order to select books or CDs. A list box will display the items of a category and the user will be able to select a single item and to display its properties. Furthermore the user may change the summary of the selected item. Here is a screenshot of the view:
The View
We will create a very simple WPF view for displaying our data. It will contain a combo box in order to select books or CDs. A list box will display the items of a category and the user will be able to select a single item and to display its properties. Furthermore the user may change the summary of the selected item. Here is a screenshot of the view:
Binding the Data
XmlDataProvider exposes several ways to access xml data
- inline xml with the x:XData element
- set the Source property to an URI
- set the Document property to a XmlDocument object
I will use the Source property and set it to the path of the xml file. I do this in code behind, inside the constructor:
var directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if(!string.IsNullOrEmpty(directory))
{
provider.Source = new Uri(Path.Combine(directory, "Inventory.xml"));
}
With the provider set up, we can now define the Binding inside the view:
<Window x:Class="XmlDataProviderSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="280" Width="600">
XmlDataProvider exposes several ways to access xml data
- inline xml with the x:XData element
- set the Source property to an URI
- set the Document property to a XmlDocument object
I will use the Source property and set it to the path of the xml file. I do this in code behind, inside the constructor:
var directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if(!string.IsNullOrEmpty(directory))
{
provider.Source = new Uri(Path.Combine(directory, "Inventory.xml"));
}
With the provider set up, we can now define the Binding inside the view:
<Window x:Class="XmlDataProviderSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="280" Width="600">
<Window.Resources>
<XmlDataProvider x:Key="dataProvider"/>
</Window.Resources>
<StackPanel>
<ComboBox x:Name="inventoryTypeComboBox" ItemsSource="{Binding Source={StaticResource dataProvider}, XPath=/Inventory/*}">
<ComboBox.ItemTemplate>
<DataTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<StackPanel Margin="0,9,0,0" Orientation="Horizontal" DataContext="{Binding ElementName=inventoryTypeComboBox, Path=SelectedItem}">
<ListBox x:Name="listBox" ItemsSource="{Binding Path=ChildNodes}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding XPath=Title}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Grid Margin="6,0,0,0" DataContext="{Binding ElementName=listBox, Path=SelectedItem}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="ISBN: "></TextBlock>
<TextBlock Grid.Column="1" Text="{Binding XPath=@ISBN}"></TextBlock>
<TextBlock Grid.Row="1" Text="Summary: "></TextBlock>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding XPath=Summary}"/>
</Grid>
</StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="60"/>
</Grid.ColumnDefinitions>
<Button Margin="3,6,3,0" Content="Save" Grid.Column="1" Click="OnSaveClicked"/>
<Button Margin="3,6,6,0" Content="Exit" Grid.Column="2" Click="OnExitClicked"/>
</Grid>
</StackPanel>
</Window>
Let’s start by examining the combo box. Its ItemsSource property is bound to the XmlDataProvider. The root node is selected by using an XPath expression. It selects all direct children of the inventory node, which are in that case books and CDs. In order to show some friendly text inside the combo box it defines an ItemTemplate, which has a TextBlock bound to the Name property of the current XmlNode. The XPath expression returns a list of XmlNode objects. Therefore you can bind to any property of that object. You could also bind to another XPath expression based on the current node.
A ListBox shall show all the items of the selected category. The data context of the container containing the list box is bound to the currently selected item of the combo box. That item is an XmlNode object, so the list box can be bound to the nodes ChildNodes collection. You don’t need to specify the Path attribute, but it makes the code more readable. Again we’re defining an ItemTemplate for the list. This time we use an XPath expression to bind to the title node in order to display the inventory item title inside the list. We could have also bound to the InnerText property of the XmlNode. Use whatever you like.
When the user selects an item in the list, its properties shall be shown next to the list and at least the summary shall be editable. The data context of the Grid container element is therefore bound to the selected item of the list box. Inside the Grid are TextBlocks for displaying the ISBN and the summary of the currently selected inventory item. The summary is displayed inside a TextBox so the user may change it. Note, that the ISBN is an attribute of the book node, so you have to use an @ symbol inside the XPath expression.
Changing and Saving Data
XmlDataProvider keeps an XmlDocument with an XmlNode object collection of the xml document in memory. Using the xml API in .NET you can do any modifications you want. What’s cool about using XmlDataProvider in WPF is that when you change the value of a bound XmlNode inside a user control, the new value will be written to the XmlNode object. That means it supports two-way binding. That makes it extremely easy to edit the summary node in our example. In order to save the changes back to the file system, you just need to call the save method of the underlying XmlDocument:
private void OnSaveClicked(object sender, RoutedEventArgs e)
{
if(provider != null && provider.Document != null)
{
provider.Document.Save(provider.Source.AbsolutePath);
}
}
Summary
The XmlDataProvider together with WPF binding makes it very easy to access, display, and modify Xml data. You can navigate through the data with just some simple XPath expressions. For small documents it is extremely fast. For larger documents consider loading the document in a background thread and assign it manually to the provider. Always remember that the XmlDataProvider is just a wrapper around an XmlDocument.
Monday, September 19, 2011
Windows 8 Developer Preview - Screenshots
Last week Microsoft showed off the Windows 8 Developer Preview at BUILD 2011 (check out the impressing keynotes). I couldn’t resist and fetched the ISO image file containing the preview and the new developer tools like Visual Studio 2011 Express and Expression Blend 5. The ISO file can be used to easily set up a Virtual Machine using Virtual Box which is freely available. I made some screenshots from the new Windows 8 Metro Style User Interface as well as from Visual Studio and Expression Blend. Check it out on my SkyDrive: Windows 8 Developer Preview Screenshots.
Wednesday, August 24, 2011
The curious world of WPF Popups
Popups in WPF sometimes appear to behave not as expected. Mostly it’s just because they are not used correctly or there’s just not enough understanding of the popups functionality and the relations to other controls. I encountered such a situation lately in a project and thought it would be worth to share some thoughts on this topic.
First of all it needs to be clear that a popup is not a window in terms of WPF. This aspect is important because a popup cannot receive focus inside an application. This again is relevant in order to understand how the StaysOpen property of the Popup class works and why a popup sometimes is not closed or opened as expected. Let’s have a look at a first example. Suppose we have the following XAML code:
<ToggleButton x:Name="toggleButton"
What would you expect to happen here? Will the popup be closed when the toggle button gets unchecked? No, it will not. When the user clicks the toggle button it changes its state to “checked”. This opens the popup, because the popups IsOpen property is bound to the toggle buttons IsChecked property. When the toggle button is clicked again the following happens:
We define our own special callback delegate for this situation. Child popups may register such a callback to get informed of mouse up events. Pay attention to use PreviewMouseUp and not just MouseUp. Otherwise you may end up with someone already handling the mouse event so you don’t get notified. In order to clean up properly we also added a method to unregister callbacks. Let’s have a look at what needs to be done in the popup:
private void popup2_Opened(object sender, EventArgs e)
When the popup opens, it adds its callback to the application main window. It does this only if it has a parent control in its logical tree which is a popup too. Additionally it subscribes to its own close event in order to properly unregister the callback. In the callback we’re looking at the source of the mouse event. If the source or one of its parents in the logical tree is a popup and this popup is not the child popup itself, then we close the child popup. There is no magic at all. To find a parent control of a given type in the logical tree the GetParent method is used. This method is implemented as follows:
private static DependencyObject GetParent(DependencyObject current, Type type)
This method uses the LogicalTreeHelper to walk up the logical tree until it finds an element of the given type. This element is then returned. With these additions to the popup and the main window we’re now able to close a child popup when we click anywhere on the parent popup.
This was a very small and simple example and I’m sure that everyone is conflicted with more complex problems and applications but I hope it gives you a starting point when you’re entering the curious world of WPF popups.
First of all it needs to be clear that a popup is not a window in terms of WPF. This aspect is important because a popup cannot receive focus inside an application. This again is relevant in order to understand how the StaysOpen property of the Popup class works and why a popup sometimes is not closed or opened as expected. Let’s have a look at a first example. Suppose we have the following XAML code:
<ToggleButton x:Name="toggleButton"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="Popup"/>
<Popup IsOpen="{Binding ElementName=toggleButton, Path=IsChecked}"
Placement="MousePoint"
StaysOpen="False">
…
</Popup>
What would you expect to happen here? Will the popup be closed when the toggle button gets unchecked? No, it will not. When the user clicks the toggle button it changes its state to “checked”. This opens the popup, because the popups IsOpen property is bound to the toggle buttons IsChecked property. When the toggle button is clicked again the following happens:
1. The toggle button receives focus. Therefore the popup is closed, because StaysOpen is set to false.
2. The IsOpen property is set to false.
3. Because of the implicit two-way binding between IsOpen and IsChekched, the “checked” status of the toggle button is set to false.
4. The toggle button receives the click event and gets checked, resulting in an open popup.
The simple solution to that problem is to define the binding above as one-way, so the closing of the popup would not change the “checked” state of the toggle button. Another possibility would be to set StaysOpen to true. This results in not closing the popup automatically when the toggle button receives focus. It is closed not until IsChecked changes.
Another problem may be that you have a popup within a popup. Imagine a popup where you have several other controls and maybe some of the controls open another popup which is then displayed over the existing popup. In this situation you would expect to close the “child” popup by clicking on the “parent” popup. But that’s just not possible with the build in functionality. Remember the statement from the beginning: Popups can’t receive focus. Therefore the StaysOpen property won’t work, because the parent popup doesn’t get the focus. This in turn means that there is no way to automatically close the child popup by clicking somewhere on the parent popup. One solution to that problem is to listen to mouse events on the application window and to route these information to “child” popups. We will see this in the following simple example:
<Window x:Class="WpfPopupTestApp.MainWindow"
2. The IsOpen property is set to false.
3. Because of the implicit two-way binding between IsOpen and IsChekched, the “checked” status of the toggle button is set to false.
4. The toggle button receives the click event and gets checked, resulting in an open popup.
The simple solution to that problem is to define the binding above as one-way, so the closing of the popup would not change the “checked” state of the toggle button. Another possibility would be to set StaysOpen to true. This results in not closing the popup automatically when the toggle button receives focus. It is closed not until IsChecked changes.
Another problem may be that you have a popup within a popup. Imagine a popup where you have several other controls and maybe some of the controls open another popup which is then displayed over the existing popup. In this situation you would expect to close the “child” popup by clicking on the “parent” popup. But that’s just not possible with the build in functionality. Remember the statement from the beginning: Popups can’t receive focus. Therefore the StaysOpen property won’t work, because the parent popup doesn’t get the focus. This in turn means that there is no way to automatically close the child popup by clicking somewhere on the parent popup. One solution to that problem is to listen to mouse events on the application window and to route these information to “child” popups. We will see this in the following simple example:
<Window x:Class="WpfPopupTestApp.MainWindow"
Title="MainWindow" Height="350" Width="525">
<StackPanel Height="29">
<ToggleButton x:Name="toggleButton"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="Popup"/>
<Popup IsOpen="{Binding ElementName=toggleButton, Path=IsChecked}"
Placement="MousePoint"
StaysOpen="True">
<StackPanel Width="100" Height="100">
<ToggleButton x:Name="togglePopupButton"
HorizontalAlignment="Center"
Content="Popup"/>
<Popup x:Name="popup2"
IsOpen="{Binding ElementName=togglePopupButton, Path=IsChecked}"
Placement="MousePoint"
StaysOpen="False"
Opened="popup2_Opened">
<StackPanel Width="50" Height="50">
<Label Content="Test"/>
</StackPanel>
</Popup>
</StackPanel>
</Popup>
</StackPanel>
</Window>
This small XAML snippet defines a toggle button that can be used to open a popup. Inside the popup is another toggle button that opens another popup inside the parent popup. The StaysOpen property of both popups is set to false so that they are automatically closed when a control receives focus. With the current setup, the child popup lacks this functionality. That’s why it needs a manual trigger. As mentioned above we will start listening on mouse events – concretely the PreviewMouseUp event – of the application window. In the event handler we will invoke previously registered callback methods to inform child popups of the event. The following additions have to be made to the application main window:
private IList<MainWindowMouseDownCallback> callbacks = new List<MainWindowMouseDownCallback>();
private IList<MainWindowMouseDownCallback> callbacks = new List<MainWindowMouseDownCallback>();
public delegate void MainWindowMouseDownCallback(object sender, MouseButtonEventArgs args);
public MainWindow()
{
InitializeComponent();
this.PreviewMouseUp += MainWindow_MouseUp;
}
public void RegisterMouseDownCallback(MainWindowMouseDownCallback callback)
{
callbacks.Add(callback);
}
public void UnRegisterMouseDownCallback(MainWindowMouseDownCallback callback)
{
if (callbacks.Contains(callback))
{
callbacks.Remove(callback);
}
}
void MainWindow_MouseUp(object sender, MouseButtonEventArgs e)
{
foreach (var callback in callbacks)
{
callback.Invoke(sender, e);
}
}
We define our own special callback delegate for this situation. Child popups may register such a callback to get informed of mouse up events. Pay attention to use PreviewMouseUp and not just MouseUp. Otherwise you may end up with someone already handling the mouse event so you don’t get notified. In order to clean up properly we also added a method to unregister callbacks. Let’s have a look at what needs to be done in the popup:
private void popup2_Opened(object sender, EventArgs e)
{
var parent = GetParent(popup2, typeof(Popup));
if (parent != null)
{
this.RegisterMouseDownCallback(PopupCallback);
popup2.Closed += popup2_Closed;
}
}
private void popup2_Closed(object sender, EventArgs e)
{
popup2.Closed -= popup2_Closed;
this.UnRegisterMouseDownCallback(PopupCallback);
}
private void PopupCallback(object sender, MouseButtonEventArgs args)
{
var obj = args.Source;
if (obj != null)
{
var parent = GetParent(obj as DependencyObject, typeof(Popup));
if (parent != null && !parent.Equals(popup2))
{
this.popup2.IsOpen = false;
}
}
}
When the popup opens, it adds its callback to the application main window. It does this only if it has a parent control in its logical tree which is a popup too. Additionally it subscribes to its own close event in order to properly unregister the callback. In the callback we’re looking at the source of the mouse event. If the source or one of its parents in the logical tree is a popup and this popup is not the child popup itself, then we close the child popup. There is no magic at all. To find a parent control of a given type in the logical tree the GetParent method is used. This method is implemented as follows:
private static DependencyObject GetParent(DependencyObject current, Type type)
{
var parent = LogicalTreeHelper.GetParent(current);
if (parent == null)
return null;
if (parent.GetType().Equals(type))
{
return parent;
}
return GetParent(parent, type);
}
This method uses the LogicalTreeHelper to walk up the logical tree until it finds an element of the given type. This element is then returned. With these additions to the popup and the main window we’re now able to close a child popup when we click anywhere on the parent popup.
This was a very small and simple example and I’m sure that everyone is conflicted with more complex problems and applications but I hope it gives you a starting point when you’re entering the curious world of WPF popups.
Subscribe to:
Posts (Atom)