Kiwi Ingenuity

Thoughts from another perspective

.NET Core 1.0.0 RC2 with VS2015 Tooling Preview 1

Today Microsoft announced the availability of .NET Core 1.0.0 RC2 with VS2015 Tooling Preview 1.

The documentation about the release is available as follows:

The last link above point to the installation. I choose the Visual Studio Official MSI Installer

Another announcement made this very same day, is the realise of Entity Framework Core RC2

I then followed this tutorial to create a ASP.NET Core MVC application

Everything worked as expected!

Don’t get too Func-y

There have been a few posts appearing this week which themed on encouraging the reader to start using the Func and Action delegates.

It started with Ian Randall (@kiwipom) suggesting to Give your code just a little Func-y love. This was followed by Ivan Towlson (@ppog_penguin) scripting Make my Func the higher-order Func, quickly followed by Func-ier and Func-ier which wanted to improve on the separation of concern.

I thought I would add my view and say to the readers – “Don’t do it!” At least not with the example given. It’s difficult to understand and convoluted!

@itsgrego posted a tweet this week bringing our attention to Why you shouldn’t comment (or Document) code. I would think the majority of us would agree with the contents of that article. I do!

So code should be easy to read, and I would encourage you to write your code like this.

        public IEnumerable GetOrders(int customerId)
        {
            string cacheKey = string.Format("OrdersForCustomer{0}", customerId);
            IEnumerable result = _cacheService.Retrieve<IEnumerable>(cacheKey);
            if (result == null)
            {
                result = _ordersRepository.GetForCustomer(customerId);
                _cacheService.Add(cacheKey, result);
            }
            return result;
        }

Yes it’s the same as Ian’s starting point and it takes up 6 lines, but isn’t it so much easier to read and you understood exactly what the coders intention is. Come back to this code some years down the track and you will understand at first glance what the coders intention is. It’s self documented and there is separation of concern.

Delegates

I must state here and now that “I love delegates” and I would encourage you all to be using them consistently throughout your projects. When you see yourself writing repetitive code (or copy / pasting) then stop and ask yourself about delegates?

I’ll take the example above and explain how I would incorporate that code in a delegate. In the real world there is more to the process about retrieving and storing data than can be described in 6 lines of code. One area of concern is error handling. If you have been wrapping your Methods in try / catch blocks then you know about repetitive code and copy and pasting.

So I’m going to change my example above to what I would consider a real world example.

        public IEnumerable GetOrders(int customerId)
        {
            return FetchMethod(delegate()
            {
                string cacheKey = string.Format("OrdersForCustomer{0}", customerId);
                IEnumerable result = _cacheService.Retrieve<IEnumerable>(cacheKey);
                if (result == null)
                {
                    result = _ordersRepository.GetForCustomer(customerId);
                    _cacheService.Add(cacheKey, result);
                }
                return result;
            });
        }

        private TResult FetchMethod(Func fetchOperation)
        {
            try
            {
                return fetchOperation();
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
            return default(TResult);
        }

In the example above I have wrapped my GetOrder code into a delegate. I then send that delegate to a function I have written to take care of my error handling.

From now on each time I have to make a call and need to handle any exception I will use this new function. Thank-you Func-y!

A WPF Text Box Autocomplete Extender using Reactive Extensions

My objective is to design an WPF auto complete text box that I can use to make calls to a web service. I was aware of the Reactive Extensions technology, but have never up to now had an opportunity to deploy an RX solution

  

Reactive Extensions

Reactive Extensions appealed to me because the amount of code required to set up an observe / search routine is minimal. The syntax is very powerful.  

As an introduction to RX I worked through the example published by PeteGoo called Building an Auto Complete control with Reactive Extensions (Rx). When I had completed the exercise I had a code snippet that showed me how to create a synchronous (or asynchronous) call to a web service, which catered for:

· Throttling (idle periods before searching)

· Merging multiple event streams

· Removing duplicate consecutive events

· Cancelling previous searches

All the above attributes were important features for my auto complete text box.

I highly recommend that before you proceed any further that you read and understand Pete Goo’s example.

 

Popup Control

What was missing from Pete Goo’s example was a Popup that would display each time text was entered into the textbox. I also wanted to have a reusable user control which would contain the repetitive code base.

The solution that appealed was the creation of Ioan Lazarciuc called Auto Complete for Textboxes in WPF. Ioan was inspired by the AutoCompleteTextBoxAutoCompleteExtender in the ASP.NET Ajax control toolkit and also because his solution requires minimum intervention of existing WPF code.

What Ioan’s solution lacked was the ability to do an asynchronous search while the operator keyed the search phrase. PeteGoo’s solution has taken care of this for us, so we have all the code snippets required to build an autocomplete textbox. All we have to do now is put it all together.

The attached solution is my suggestion how to implement an auto complete textbox in WPF that allows asynchronous search capabilities to a web service. I will not be going over what my two contributors have already scripted, so you may want to study their solutions first before proceeding.

 

TextBoxAutoCompleteExtender

My extender is a WPF user control that handles all the background tasks when the operator keys a search into the selected textbox.

To call my extender is very simple.

<StackPanel.Resources>
   <!--Set up a ObjectDataProvider which contains the data we 
   intend to lookup-->
   <ObjectDataProvider ObjectType="{x:Type local:MyDataProvider}"
                       MethodName="DoSearch"
                       x:Key="doSearch" >
            <ObjectDataProvider.MethodParameters>
                <x:Static Member="system:String.Empty" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </StackPanel.Resources>
    <Label Content="Type in Search Phrase:" />
    <TextBox x:Name="textBox" />
    <ac:TextBoxAutoCompleteExtender x:Name="autoTxtBox"
                                    TargetControl="{Binding ElementName=textBox}"
                                    SearchDataProvider="{Binding Source={StaticResource doSearch}, 
				                                    BindsDirectlyToSource=True}" />
</StackPanel>

And that it!

Execute the application and the popup will display suggestions as you are typing characters into you TextBox.  You can use your keyboard or the mouse to select the correct phrase.

You can download my source code and example here.

Drag and drop solution for your WPF application

Last week I needed to include drag / drop capabilities on a Tree View on a WPF application.

 

As usual I started cutting the code required to give me the required capabilities. After some time it became obvious that Drag Drop functionality in the MVVM world was more complicated than what I first thought. All my code was residing in code behind instead of the view model?

 

I took some time out to search the internet to find out how others have resolved this issue. There are many solutions to found.

 

I did however discover one solution that I thought was very well done. Steven Kirk (back in 2009) has created a library that he calls gong-wpf-dragdrop.

 

His web site says:

 

The GongSolutions.Wpf.DragDrop library is a drag'n'drop framework for WPF. It has the following features:

  • Works with MVVM : the logic for the drag and drop can be placed in a ViewModel. No code needs to be placed in codebehind, instead attached properties are used to bind to a drag handler/drop handler in a ViewModel.
  • Works with multiple selections.
  • Can drag data within the same control to re-order, or between controls.
  • Works with TreeViews.
  • Can insert an item into a collection, or drop one item onto another.
  • Can display Adorners to give the user visual feedback of the operation in progress.
  • Has sensible defaults so that you have to write less code for common operations

I found this library very easy to use and would recommend you consider this solution if you want to add drag drop capabilities to your WPF application.

Temporary Storage Service for WPF

Sometimes there is a requirement to temporarily store an object that can be later retrieved.  My particular problem at the time was that I wanted to share a View Model with a second view, but alas neither view knows about one another.

My first thought was to store the view model object temporarily in a Unity Container.  That way I could easily retrieve the object at a later time. This solution was not satisfactory however because this was only suppose to be a temporary storage solution and Unity does not support any unregister operation.  Not having the ability to remove (unregister) the object was not an option.

My solution was to create a Temporary Storage Service. The service I am demonstrating here allows for the Deposit and the Withdrawal of data (objects).  Some people may want to store the data for a little bit longer than straight in and straight out.  This solution could easily be modified to suit.

My Temporary Storage Service looks like this.

public class TemporaryStorageService : ITemporaryStorageService
{
    public void Deposit<T>(Object o, string key)
    {
        System.Windows.Application.Current.Properties[key] = o;
    } 

    public T Withdraw<T>(string key)
    {   T o = (T)System.Windows.Application.Current.Properties[key];
        System.Windows.Application.Current.Properties.Remove(key);
        return o;
    }
} 

 

The Interface

publicinterface ITemporaryStorageService
{
   void Deposit<T>(Object o, string key);
   T Withdraw<T>(string key);
}

Register the service with Unity

// Temporary Storage Service
ITemporaryStorageService temporaryStorageService = new TemporaryStorageService();
unityContainer.RegisterInstance<ITemporaryStorageService>(temporaryStorageService);

 

Now I can call my Service whenever I need to store any Objects temporarily.  As I said above my immediate need was to store a view model temporarily.  So this is what I did.

My first view creates a new view model and immediately puts it in temporary storage

public class SomeWindow : Window
{
    ITemporaryStorageService _temporaryStorageService; 

    public SomeWindow(ITemporaryStorageService temporaryStorageService)
    {
        this._temporaryStorageService = temporaryStorageService;
        InitializeComponent();
    } 

    [Dependency]
    public SharedViewModel VM
    {
        set
        {
            this.DataContext = value;


            // We will store the view model in the Application Properites
            this._temporaryStorageService.Deposit<SharedViewModel>(value, "SharedViewModel");
        }
    }
} 

 

Then when I initialise my second view I call upon the stored viewmodel.

[Dependency]
public CashBook.MVVM.Services.ITemporaryStorageService TemporaryStorageService
{
   set
   {
      this.DataContext = value.Withdraw<SharedViewModel>("SharedViewModel");
   }
}

 

Works like a charm!

My First WPF Report

My first WPF application is near completion, but one of the last items on the list is report printing. After a couple of hours on the internet I really did not see an ideal solution. There were however some aspects of the solutions I saw that appealed so I decided that I would pick out the best bits of what I had found and script my own Report Writer.

One example that got my attention on the internet was Azam Sharp. I thought his Flow Document example was simple and clean solution. What I wanted to do was take Azam’s example to the next level and give myself a tool to quickly design a report for my new project.

My Requirement list went like this.

  1. Print Preview
  2. Page Header
  3. Page Footer
  4. Full control of the report layout
  5. Keep it simple.

I will demonstrate my solution using a similar Business Entity as Azam did.

    public class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }

        // I'll add another column as one should always try and improve a copied solution <g>.
        public string Phone { get; set; }
    }

My Customers Class will mange the Customer Collection

    public class Customers
    {
        List<Customer> _customers = new List<Customer>();

        public Customers()
        {
            for (int i = 1; i <= 80; i++)
            {
                Customer customer = new Customer();
                customer.FirstName = "FirstName " + i;
                customer.LastName = "LastName " + i;
                customer.Phone = "Phone " + i;
                _customers.Add(customer);
            }
        }

        public List<Customer> FullCustomerList { get { return _customers; } }

        public int CustomerCount { get { return _customers.Count(); } }

        public Customer[] GetReportLineItems(int skipCount, int takeCount)
        {
            var list = (from c in _customers
                        select c).Skip(skipCount).Take(takeCount);
            return list.ToArray(); ;
        }
    }

The operator will select and confirm the printing properties from the standard Print Dialog. I have designed a small class to record the values from the print dialog which we will use for formatting our report.

    internal class PageLayout
    {
        public PageLayout(double height, double width)
        {
            this.PageHeight = height;
            this.PageWidth = width;
            this.Margin = new Thickness(80, 50, 80, 50);
            this.ListViewItemsCount = 48;
        }

        public double PageHeight { get; private set; }
        public double PageWidth { get; private set; }
        public Thickness Margin { get; private set; }
        public double PrintAreaHeight { get { return PageHeight - Margin.Top - Margin.Bottom; } }
        public double PrintAreaWidth { get { return PageWidth - Margin.Left - Margin.Right; } }
        public int ListViewItemsCount{ get; private set; }
    }

The 'ListViewItemsCount' is most probably not the flashest coding mythology. I will elaborate in this later in this paper.

Next we want to design a Customer Report Template. We do this using XAML. The rules are no different, than if we where designing a form.

    <DockPanel x:Name="LayoutDockPanel" LastChildFill="True">
        <!-- Header -->
        <StackPanel DockPanel.Dock="Top" Height="80">
            <TextBlock FontSize="24" >Customer Report</TextBlock>
            <TextBlock FontSize="24" >Full Listing</TextBlock>
        </StackPanel>
        <!-- Report Footer -->
        <StackPanel DockPanel.Dock="Bottom" Height="20" >
            <TextBlock HorizontalAlignment="Center" Margin="0,5,0,0" >Printing via a Flow Document</TextBlock>
        </StackPanel>
        <!-- Report Body -->
        <ListView Name="ListView" HorizontalAlignment="Center" BorderThickness="0" >
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="FirstName" DisplayMemberBinding="{Binding FirstName}" Width="110"  />
                    <GridViewColumn Header="LastName" DisplayMemberBinding="{Binding LastName}" Width="110" />
                    <GridViewColumn Header="Phone" DisplayMemberBinding="{Binding Phone}" Width="110"  />
                </GridView>
            </ListView.View>
        </ListView>
    </DockPanel>

The Print Layout I have placed in a user control and it is here where I have total control over my report content. There is a page header, page body and a page footer section. If you think this through your layout options a virtually unlimited?

Now let put this altogether! I create a Print Preview window. The XAML looks like this.

    <DockPanel Width="Auto" Height="Auto" LastChildFill="True">
        <Button Width="100" Height="50" DockPanel.Dock="Top" Click="SendReportToPrinterButtonClick">Send to Printer</Button>
        <FlowDocumentReader >
            <FlowDocument x:Name="customerReport" Background="White" />
        </FlowDocumentReader>
    </DockPanel>

The Code behind looks like this.

    public partial class PrintPreview : Window
    {
        private Customers _vm;
        private PrintDialog _printDialog;

        public PrintPreview()
        {
            InitializeComponent();

            _vm = new Customers();

            _printDialog = new PrintDialog();
            if (_printDialog.ShowDialog() == true)
            {
                PageLayout pageLayout = new PageLayout(_printDialog.PrintableAreaHeight, _printDialog.PrintableAreaWidth);
                this.BuildReport(pageLayout);
            }
        }

        private void BuildReport(PageLayout pageLayout)
        {
            // Set the page Size and Margins
            this.customerReport.PagePadding = pageLayout.Margin;
            this.customerReport.PageHeight = pageLayout.PageHeight;
            this.customerReport.PageWidth = pageLayout.PageWidth;
            this.customerReport.ColumnWidth = pageLayout.PageWidth;
            this.customerReport.ColumnGap = 0;

            // Body Content
            for (int i = 0; i < _vm.CustomerCount; i += pageLayout.ListViewItemsCount)
            {
                CustomerReportTemplate layout = new CustomerReportTemplate();
                // The next two lines are important as it will place the 
                // header and footer in place and the rest of the page area
                // is for the page body content.
                layout.LayoutDockPanel.Height = pageLayout.PrintAreaHeight;
                layout.LayoutDockPanel.Width = pageLayout.PrintAreaWidth;

                layout.ListView.ItemsSource = _vm.GetReportLineItems(i, pageLayout.ListViewItemsCount);

                InlineUIContainer inlineContainer = new InlineUIContainer();
                inlineContainer.Child = layout;

                this.customerReport.Blocks.Add(new Paragraph(inlineContainer));

            }
        }

This is the code that drives the report content. Although you may see some evidence of MVVM in this snippet, it is not an objective in this paper to provide a true MVVM example.

The above snippet achieves:

  • Connecting to the data source.
  • Showing the Print Dialog, so that the user can select the desired printer.
  • Using the information from the print dialog set up report layout.
  • Calls on the data source for the report body content data.
  • After the operator has studied the print preview, send the report to the printer.

I want to bring your attention to how I defined the page layout (page size, margins) and also how I have completely avoided scripting a Document Paginator. Neil Knobbe has a blog where he deployed this this mythology, which I have borrowed. He emphasises how it is important to configure the flowdocument page, column and margin sizes.

List View Item Count

In my example I assigned a value to the ListViewItemCount. This property returns the number of rows I wish to print in the body of the my document. Now obviously this value depends on the paper orientation and the paper size in your printer. So really it needs to be calculated based on these other variables. The good news is that it can be calculated. At least it can be calculated if you are happy to agree with the following logic.

  1. This is a business report that accompanies your application. Once this report is designed it will not change much. We may want to give the operator the choice of Portrait or Landscape. The font and font size will be pretty much static. The paper size could possibly change, but in the majority of cases you will have designed your report to fit one paper size.
  2. If you study my Customer Report Template above you will see I have started with a DocPanel. Added a Header and a Footer and the rest of the space is for the Page Body. The height of the body area is dependent on the Print Dialog Printable area height, our margin and the space taken up by the header and footer.
  3. This suggests that the item count value could be as simple as providing a portrait orientation value or a Landscape orientation value. What are these values? If you go now and change the value for ListViewItemCount to a large number (say 130) and run the reports in both portrait and landscape the the answer will be quickly evident. Give it a go.
  4. If you do have several paper sizes that your operator has to choose from then it's a bit more complicated. However as I leaded to above, we can easily calculate the page body height and we can also easily calculate the height of each row. The rest I will leave up to you.

This example is a good base for printing Business Reports. If I was printing many reports on my project then a lot of the above code is reusable, so it would not take a long time to push out other reports as they are required.

Source Code

You can download the Source here.

WCSF - Sharing the Controller

While working on a Web Client Software Factory solution, I found myself in a situation where I wanted several presenters to share the same controller.

How this came about was that I had a page that deployed several User Controls that had their own presenters.  These same User Controls needed to communicate with one another, so sharing the same controller, was the solution I needed to deploy.

Mats Lycken had obviously needed to solve the same problem some months earlier and has posted a solution that certainly did the job for me.  He has published a [CreateShared] attribute which can be deployed to replace [CreateNew].

The [CreateShared] attribute enabled me to share the same Controller.  Mats has provided us with library which needs to be included in our project as well as a working example to see how to use the new attribute.

Further documentation can also be found here.  This link refers to a solution that Mats posted in the WCSF Contrib.  I also tried the Contrib solution and have to confess it left me rather confused?  My recommendation is to follow the first link above.

Thank-you Mats for a fine effort!

Implementing a Custom IProxyFactory using the DSA deployed by SCSF

When deploying WCF security, for a Smart Client Service Factory (SCSF) solution the documentation encourage the developer to deploy an EndPointCatalog.  I found this to be a lot of coding when all I wanted to do was simply pass a username and password to the proxy so that it would call the service with the correct credentials.

My workaround is to not create a “EndPoint” section in your client app.config but instead override the GetOnlineProxy Method in the Microsoft.Practices.SmartClient.DisconnectedAgent.WCFProxyFactory class.

Assuming you have a Service Agent (or similar) Module in your SCSF solution create a new class that inherits the WCFProxyFactory class mentioned above.

using System;
using System.Net;
using System.Reflection;
using System.ServiceModel;
using System.ServiceModel.Description;
using Microsoft.Practices.SmartClient.EndpointCatalog;
using Microsoft.Practices.SmartClient.DisconnectedAgent;
namespace MyNamespace
{
   public class WCFProxyFactory : Microsoft.Practices.SmartClient.DisconnectedAgent.WCFProxyFactory
               where TChannel : class
   {
      public override object GetOnlineProxy(Request request, string networkName)
      {
         Guard.ArgumentNotNull(request, "request");
         ClientBase proxy = (ClientBase)Activator.CreateInstance(request.OnlineProxyType);
         // Set the credentials
         ClientCredentials clientCredentials = proxy.ClientCredentials;
         clientCredentials.UserName.UserName = "myusername";
         clientCredentials.UserName.Password = "mypassword";
         return proxy;
      } 
   }
}

You will need to create a Guard Class which you can simply copy from the source code that comes with SCSF (i.e. Microsoft.Practices.SmartClient.DisconnectedAgent.Guard) and then your solution should successfully compile.

Lastly you need to change the default offlinebehavoir of your Agent which was generated by the Disconnected Service Agent. Look for the GetAgentDefaultBehavior method

public static OfflineBehavior GetAgentDefaultBehavior()
{
   OfflineBehavior behavior = new OfflineBehavior();
   behavior.MaxRetries = 3;
   behavior.Stamps = 1;
   behavior.Expiration = DateTime.Now + new TimeSpan(1, 0, 0, 0);
   // behavior.ProxyFactoryType = typeof(Microsoft.Practices.SmartClient.DisconnectedAgent.WCFProxyFactory);
   behavior.ProxyFactoryType = typeof(MyNamespace.WCFProxyFactory);
   return behavior;
}

Compile and start your application and it will now pass the credentials on to your service.

SCSF - View Removal and Disposal

There are instances where on closing a Work Item View, you would also like to dispose of the footprint.  Here is how it done.

Change the OnCloseView of the Presenter as follows:

#region Closing the View
/// <summary>
/// Close the view
/// </summary>
public void OnCloseView()
{
   base.CloseView();

   // If this presenter has created any workspaces
   // be sure to remove them first.
   // e.g. if (WorkItem.Workspaces.Contains(WorkSpaceName))
   //         WorkItem.Workspaces.Remove(WorkItem.Workspaces[WorkSpaceName]);

   // Remove the View from the SmartParts Collection
   this.WorkItem.SmartParts.Remove(View);

   // As we are closing and re-creating this view
   // several times, we need to Dispose the view.
   if (View is IDisposable)
      ((IDisposable)View).Dispose();

}
#endregion

Open the code behind the  that the presenter controls and add the following Code snippet.

#region Closing the View
void ParentForm_FormClosed(object sender, FormClosedEventArgs e)
{
   _presenter.OnCloseView();
}
#endregion

Finally on the same page change the OnLoad Method so it reads:

protected override void OnLoad(EventArgs e)
{
   _presenter.OnViewReady();
   base.OnLoad(e);

   // Capture the Form Close Event, because we want to destroy 
   // the view on Closing the form

   this.ParentForm.FormClosed += new FormClosedEventHandler(ParentForm_FormClosed);
}

 

And that’s it.   Each time you close the view it will be destroyed and the memory released.