I’ve spent the last few weeks laid up with knee surgery.  In that time I’ve revisited some hobby stuff including WorldBankBBS.  Testing with Synchterm normally goes well, but when testing at 2400 baud it’s not entirely accurate.

The solution is to use WinVICE (the Versatile Commodore Emulator) to actually emulate a Commodore 64 connecting to the BBS.  To make that work, you need another program called TCPSER.  This program is a GNU/Linux native app and requires Cygwin to run on Windows.  There is a Java port called TCPSER4J, and it works fine, but you get all of the problems of having Java installed on your system.

One of the things that is a big bonus of porting TCPSER4J to C# is that it allows the application to be run as a Windows Service which ensures you always have it running.

You can check out the code at https://github.com/sharpninja/tcpsersharp and you can check out the project at http://thesharp.ninja/tcpsersharp where you can download the installer.

 

An extension method that will be making its way into the Generic Extension Methods library is one I want to share tonight.  It’s for projecting an action N times.  Why such a method doesn’t already exist baffles me!

        public static T Project<T>(this T projected, int n, Action<T> action)

        {

            for (int i = 0; i < n; ++i) action(projected);

            return projected;

        }

Usage could not be simpler, any object can be projected to the specified action any number of times.

        public static int Method()

        {

            var value = 1;

            return value.Project(10, i => i*=i);

        }

 

The projection in this case yields 10^10 as the answer.  Overly simplistic example, but makes the point succinctly.

I have been working on a very interesting project lately for work. It’s a set of plugins for IE and Chrome to capture visited URLs and report them to a central server so that a remote service can be paused while the user is visiting a page in a blacklist.

To accomplish this, there is a browser helper object written Visual C++. BHO component should not be written in .net code despite the examples on the web. This is because the browser liberally shuts down COM containers which can leave the CLR in an unstable state. Trust me on this one, just bite the bullet and write your BHOs in C++.

For Chrome, things are even more convoluted. You must create a plugin in JavaScript. The manifest must declare both a background page/js and an event js file. The event js has access to the DOM, so any manipulation must be done there. The event then uses internal messaging to talk to the background js. Finally, the background js uses native messaging to talk to a command line app written in C# that accepts communications via standard in. The C# app then calls a WCF service that aggregates all of the data collected by the IE and Chrome plugins.

Did I mention that the BHO hosts its own CLR to communicate with the WCF service, too?

The WCF service is hosted in a Windows Service which also contains a cache that the WCF service populates. Once a page transaction is comple, the cache attempts to send the page data to a webapi on a central server.

Whew!

For years I’ve resisted ASP.Net MVC and WebAPI.  I am (slowly) coming around to the popular opinion that they are a good technologies, but only when applied to the appropriate tasks.  I’m also working with Single Page Applications using Knockout JS.  I’m having a bit more trouble moving to the dark side on that one.  My complaints and concerns about JavaScript-heavy applications are being somewhat justified by my experiences thus far.

My tasks thus far have been very entertaining.  I’ve written a database driven rules engine that compiles rules to CLR code via the Code DOM.  I’ve built pages for our SPA, a task that has taught me a lot about ASP.Net MVC.  Most recently I’ve been working on how to improve performance of the SPA by (gasp) moving code out of the JavaScript and back into the server.  Not only that, but we’re moving the AJAX calls from MVC controllers to WebAPI.  I’ll be posting another article soon about why you should avoid MVC controllers for AJAX when using JSON to pass around the data.

So I’m very much enjoying my new job.  I’m loving having a team of people to work with that can related to my daily challenges, and it’s been refreshing to work for a manager that isolates us from the office politics and allows us to do our work!

 

INTRODUCTION: Over a two part series I introduced how to use an MVC pattern with a Universal Windows App.  That example simply gave a list of Game of Thrones characters for display.  I’ve extended the example to also allow editing those characters in a details page.  I’ve also added a singleton to control application state and to perform navigation.

Let’s first take a look at the Singleton, which I’ve named ApplicationSingleton.  I’ve moved the instantiation of the Controller to this class as well as removed code in App.xaml.cs that used the Frame.  Instead of a navigation frame, our Singleton will assign instances of MainPage and DetailsPage to the Window Context as the user navigates the app.

EXAMPLE: App.xaml.cs Changes

        /// <summary>
        /// Invoked when the application is launched normally by the end user.  Other entry points
        /// will be used such as when the application is launched to open a specific file.
        /// </summary>
        /// <param name="e">Details about the launch request and process.</param>
        protected override void OnLaunched(LaunchActivatedEventArgs e)
        {

#if DEBUG
            if (System.Diagnostics.Debugger.IsAttached)
            {
                this.DebugSettings.EnableFrameRateCounter = false;
            }
#endif

            Window.Current.Content = ApplicationSingleton.Instance.MainPage;
            Window.Current.Activate();
        }

Now that we have the App setting it’s initial page with the Singleton, we’ll take a look at the Singleton itself.

EXAMPLE: ApplicationSingleton Code

using System.Collections.Generic;
using Windows.UI.Xaml;
using SharpNinja.Controllers.People;
using SharpNinja.Models.BlogEntities;
using SharpNinja.Utilities.MvcBasics;

namespace SharpNinja.UI.Windows10Sample2.Singletons
{
    internal class ApplicationSingleton
    {
        private ApplicationSingleton()
        {
            _personsController.Initialize(new List<IView> { _listView, _detailsView });
        }

        private readonly static ApplicationSingleton _instance = 
            new ApplicationSingleton();

        public static ApplicationSingleton Instance => _instance;

        private readonly PersonsController _personsController = 
            new PersonsController();

        private MainPage _listView = new MainPage();
        public MainPage MainPage => _listView;

        private DetailsPage _detailsView = new DetailsPage();
        public DetailsPage DetailsView => _detailsView;

        private AppState _state = AppState.List;

        public void Navigate(AppState state, params object[] values)
        {
            switch (state)
            {
                case AppState.List:
                    Window.Current.Content = _listView;
                    _state = AppState.List;
                    break;

                case AppState.Details:
                    Window.Current.Content = _detailsView;
                    var person = values[0] as Person;
                    _detailsView.InvokeLoadPersonModel(person.Name);
                   _state = AppState.Details;
                    break;
            }
        }
    }

    internal enum AppState { List, Details }
}

The Singleton is used to not only manage the state of the application, but to instantiate and register the pages of the application with the PersonsController (which has not changed at all to accomodate the changes in the User Interface).

The MainPage had to be updated a little to handle the SelectedItemChanged event so that users can click a character and open their details.

EXAMPLE: MainPage.xaml Changes

        <ListView Name="lstResults" Grid.Row="1" HorizontalAlignment="Stretch"
                  SelectionChanged="Selector_OnSelectionChanged">

EXAMPLE: MainPage.xaml.cs Changes

        private void Selector_OnSelectionChanged(object sender, 
            SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count == 1)
            {
                var person = e.AddedItems[0] as Person;

                ApplicationSingleton.Instance.Navigate(AppState.Details, person);
            }
        }

We now have our navigation and MainPage changes.  We can now look at the XAML for our DetailsPage.

EXAMPLE: DetailsPage.xaml Code

<Page
    x:Class="SharpNinja.UI.Windows10Sample2.DetailsPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SharpNinja.UI.Windows10Sample2"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" 
    >
    <Page.TopAppBar>
        <AppBar Height="50" Background="Black" IsOpen="True">
            <AppBarButton Height="50" Name="btnBack" Click="ButtonBase_OnClick">
                <TextBlock Margin="5 0 5 0">Back</TextBlock>
            </AppBarButton>
        </AppBar>
    </Page.TopAppBar>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Border Grid.Row="0" BorderThickness="5" CornerRadius="7" 
                Background="Blue" BorderBrush="Yellow" 
                Margin="10 5 10 7" Padding="8" Name="nameBorder">
            <TextBlock Text="{Binding Name, Mode=OneWay}"/>
        </Border>

        <Grid Grid.Row="1" Margin="10 5 10 7">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="5 0 5 0">First Name:</TextBlock>
            <TextBox Grid.Row="0" VerticalAlignment="Center" Grid.Column="1" Text="{Binding FirstName, Mode=TwoWay}"/>
            <TextBlock Grid.Row="1" VerticalAlignment="Center" Grid.Column="0" HorizontalAlignment="Left" Margin="5 0 5 0">Last Name:</TextBlock>
            <TextBox Grid.Row="1" VerticalAlignment="Center" Grid.Column="1" Text="{Binding LastName, Mode=TwoWay}"/>
            <TextBlock Grid.Row="2" VerticalAlignment="Center" Grid.Column="0" HorizontalAlignment="Left" Margin="5 0 5 0">Date of Birth:</TextBlock>
            <DatePicker Grid.Row="2" VerticalAlignment="Center" Grid.Column="1" Date="{Binding DateOfBirth, Mode=TwoWay}"/>
            <TextBlock Grid.Row="3" VerticalAlignment="Center" Grid.Column="0" HorizontalAlignment="Left" Margin="5 0 5 0">Age:</TextBlock>
            <TextBlock Grid.Row="3" VerticalAlignment="Center" Grid.Column="1" Text="{Binding Age, Mode=OneWay}"/>
        </Grid>
        <Border Grid.Row="2" BorderThickness="5" CornerRadius="7" 
                Background="Blue" BorderBrush="Yellow" 
                Margin="10 7 10 7" Padding="8" Name="statusBorder">
            <TextBlock Name="lblStatus"/>
        </Border>

    </Grid>
</Page>

EXAMPLE: DetailsPage.xaml.cs Code

using System;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using SharpNinja.Controllers.People.Views;
using SharpNinja.Models.BlogEntities;
using SharpNinja.UI.Windows10Sample2.Singletons;

namespace SharpNinja.UI.Windows10Sample2
{
    public sealed partial class DetailsPage : Page, IPersonDetailsView
    {
        public DetailsPage()
        {
            this.InitializeComponent();
        }

        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            ApplicationSingleton.Instance.Navigate(AppState.List);
        }

        // From IView 
        public void SetStatus(string message, bool isError)
        {
            lblStatus.Text = message;
            statusBorder.Background =
                new SolidColorBrush(isError ? Colors.Red : Colors.Blue);
        }

        public Person Model { get; set; }
        public event EventHandler<string> LoadPersonModel;

        internal void InvokeLoadPersonModel(string name)
        {
            LoadPersonModel?.Invoke(this, name);
            DataContext = Model;
        }

    }
}

The DetailsPage uses two way binding on the Model property (an instance of the Person object defined in the IPersonDetailsView interface).  This allows the UI and Model to be updated in real time.  Because the List page uses the ObservableCollection to hold all of the instances of the Person object, even the MainPage gets updated so when you go back to it, you see the changes immediately without having to refresh the search!

CONCLUSION: Using the MVC pattern along with a Singleton is a very, very powerful method of engineering any application.  Here we see it working beautifully with a Universal Windows Application, but it could just as well be WinForms or ASP.Net.  MVVM is not the end-all-be-all of XAML-based development.  Whether you are using Silverlight, WPF, Windows Store App, or Universal Windows App, you can still use the tried and true MVC, and you get a more portable framework to boot.

INTRODUCTION: Today I got a call from a recruiter looking to fix a big problem that a client is having with bad decisions being made with about code, deployment, testing… you name it.  I expressed to the executive that called me for an interview that nothing was going to get fixed without culture change, to which he said not to worry about that because he was ordering culture change and it would happen.  Well, a pack of developers can be like a pack of teenagers… They will see any change to the way they do things as an attack on their self-worth, which then leads into a ton of passive-aggressive behavior on the part of the group that will either lead to mass firings or an organizational change near the top. 

If you want culture change in a development group, it takes time, patience and a leader with a vision that the pack will buy into.  It takes someone with the background in the new techniques that the pack can hang their hat on.  It takes concrete examples of how to accomplish the new techniques.  Finally, it takes someone willing to teach the new techniques in a way that the developers take ownership in the learning and not just being lectured to.

CONCLUSION: I politely turned down the position.  I don’t want to waste their time because the pack would just see me as part of the problem of the forced changes and I don’t care to spend my time fighting a battle like that.

INTRODUCTION In part one of this series we built a simple MVC framework for our GoT character search engine. Now let’s look at how we can expand it actually provide a user interface via a Windows 10 Universal App. BTW, all of the code for this app is on GitHub.

We’ve already defined the first interface for our app, IPersonListView in the previous article.

Now we’ll implement that view with our MainPage of our search engine app.

EXAMPLE 1

using System;
using System.Collections.ObjectModel;
using System.Linq;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using SharpNinja.Models.BlogEntities;
using SharpNinja.UI.Windows10Sample.Controllers;
using SharpNinja.UI.Windows10Sample.Views;

namespace SharpNinja.UI.Windows10Sample
{
    public sealed partial class MainPage : Page, IPersonsListView
    {
        // Our controller
        private PersonsController _controller = new PersonsController();

        public MainPage()
        {
            this.InitializeComponent();

            // Initialize the controller
            _controller.Initialize(new []{this});
        }

        // From IView 
        public void SetStatus(string message, bool isError)
        {
            lblStatus.Text = message;
            statusBorder.Background = 
                new SolidColorBrush(isError ? Colors.Red : Colors.Blue);
        }

        // The Persons list
        public ObservableCollection<Person> PersonsList { get; set; }

        // Tells the controller to find the persons based on the 
        // provided partial string.
        public event EventHandler<string> FindPersons;

        // Bind the results;
        public void BindPersonsList()
        {
            // Views are responsible for sorting data
            // based on user preferences.
            lstResults.ItemsSource = 
                new ObservableCollection<Person>(
                    PersonsList.OrderBy(x => x.Name));
        }

        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            // Use null propagation to invoke our search.
            FindPersons?.Invoke(sender, txtSearchTerm.Text);
        }
    }
}

Here’s the XAML…

EXAMPLE 2

<Page
    x:Class="SharpNinja.UI.Windows10Sample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SharpNinja.UI.Windows10Sample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Border Grid.Row="0" BorderThickness="5" CornerRadius="7"
                Background="DarkBlue" BorderBrush="Yellow" 
                Margin="10 7 10 7" Padding="8">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Column="0">Search Term</TextBlock>
                <TextBox Grid.Column="1" Name="txtSearchTerm"/>
                <Button Grid.Column="2" Click="ButtonBase_OnClick">GO!</Button>
            </Grid>
        </Border>
        <ListView Name="lstResults" Grid.Row="1" HorizontalAlignment="Stretch" >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid HorizontalAlignment="Stretch">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="20" />
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Grid.Column="0" 
                                   Text="{Binding Path='Age', Mode=OneWay}" />
                        <TextBlock Grid.Column="2" 
                                   Text="{Binding Path='Name', Mode=OneWay}" 
                                   HorizontalAlignment="Stretch"/>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Border Grid.Row="2" BorderThickness="5" CornerRadius="7" 
                Background="Blue" BorderBrush="Yellow" 
                Margin="10 7 10 7" Padding="8" Name="statusBorder">
            <TextBlock Name="lblStatus"/>
        </Border>
    </Grid>
</Page>

In future articles I’ll spend more time on this example and how all of the databinding works, but for now know that the basic flow is that the user types some text to search for, clicks “GO” and then the controller finds the matching Persons and tells the View to bind to it.

CONCLUSION: Really that’s about it for the search engine. In the next post in this series we’ll look at extending the application to include a second page for entering or editing people.

INTRODUCTION: Today a user asked a very good question on Stack Overflow about adding more data to a DataGrid as the user nears the bottom of the grid.

It was an easy enough problem to solve, so I whipped together a sample app and am writing this article to further document it.

First, you’re XAML (this time in WPF format) needs to be defined. Normal instinct would be to let the DataGrid show it’s scrollbar as necessary, but in this case you should suppress that behavior and use a ScrollViewer because the ScrollView allows you to capture a ScrollChange event and the DataGrid does not.

EXAMPLE 1

<Window x:Class="GridExpansion.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:GridExpansion"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ScrollViewer VerticalScrollBarVisibility="Visible" 
                      ScrollChanged="ScrollViewer_OnScrollChanged" 
                      PreviewMouseWheel="UIElement_OnPreviewMouseWheel">
            <DataGrid x:Name="dg" VerticalScrollBarVisibility="Disabled"></DataGrid>
        </ScrollViewer>
            <DataGrid x:Name="dg" VerticalScrollBarVisibility="Disabled"></DataGrid>
        </ScrollViewer>
    </Grid>
</Window>

Next, we need our code behind which contains the code to initialize our grid and add more data on demand.

EXAMPLE 2

using System;
using System.Data;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;

namespace GridExpansion
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            CreateTable();

            dg.AutoGenerateColumns = true;
            dg.ItemsSource = EmployeeDataTable.DefaultView;
        }

        private DataTable employeeDataTable;
        private bool _addingData;

        public DataTable EmployeeDataTable
        {
            get { return employeeDataTable; }
            set
            {
                employeeDataTable = value;
            }
        }

        private void CreateTable()
        {
            EmployeeDataTable = new DataTable("EmployeeDataTable");
            EmployeeDataTable.Columns.Add("Row", typeof(int));
            EmployeeDataTable.Columns.Add("0", typeof(string));
            EmployeeDataTable.Columns.Add("1", typeof(string));
            EmployeeDataTable.Columns.Add("2", typeof(string));
            EmployeeDataTable.Columns.Add("3", typeof(string));
            EmployeeDataTable.Columns.Add("4", typeof(string));
            EmployeeDataTable.Columns.Add("5", typeof(string));
            EmployeeDataTable.Columns.Add("6", typeof(string));
            EmployeeDataTable.Columns.Add("7", typeof(string));
            EmployeeDataTable.Columns.Add("8", typeof(string));
            EmployeeDataTable.Columns.Add("9", typeof(string));

            GetNewData();
            GetNewData();
            GetNewData();
        }

        private void GetNewData()
        {
            for (int i = 0; i < 20; i++)//Adding 20 DataRows
            {
                var theRow = employeeDataTable.NewRow();
                theRow[0] = employeeDataTable.Rows.Count;
                for (int j = 1; j < 11; j++)
                {
                    theRow[j] = j % 2 == 0 ? "a" : "b";
                }
                Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() =>
                {
                    employeeDataTable.Rows.Add(theRow);
                }));
            }
        }

        private void ScrollViewer_OnScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            var sv = sender as ScrollViewer;

            if (sv != null && !_addingData)
            {
                if (sv.ScrollableHeight - e.VerticalOffset == 0)
                {
                    _addingData = true;
                    GetNewData();
                    _addingData = false;
                }
            }
        }

        private void UIElement_OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            ScrollViewer scv = (ScrollViewer)sender;
            scv.ScrollToVerticalOffset(scv.VerticalOffset - e.Delta);
            e.Handled = true;
        }
    }
}

CONCLUSION: The magic is in the ScrollViewer_OnScrollChanged event handler. We simply check if the scrollable height == the vertical height of the event args and if they are the same then we add more data.

Posted in WPF.

INTRODUCTION: There are a lot of reasons to use real apps on the desktop:

  • Chrome can use over 1GB of RAM and runs continuously.  Universal apps typically do not.
  • Over 70% of the web is written in PHP.  Of those, 81% are vulnerable to attack.  Universal apps are almost impossible to attack without physical access to your desktop.
  • Tabbed browsers are like poor window managers trying to co-opt good window managers.
  • Universal apps don’t need a bloated javascript engine to get 1/10th of the performance of compiled code.

CONCLUSION:  For many applications, the web is the way to go.  Think corporate presence, branding, publishing, etc.  Written in a responsible manner these can be good netizens.  We’ve already seen in the phone segment that people prefer apps that are tailored to their application, not just another bootstrap website running in a browser that depends on a far-away server for everything.  It’s time for a Desktop Renaissance and Universal Apps can get us there.