Thursday, September 6, 2018

C# Displays with and without WPF



To extend my eXploratory Project I decided to interface to a display application as I had previously done with the Ada version.  With the Ada version I used C# with Windows and Mono with Linux for the display application since they have display control/widget support built in.  Since the current C# based framework is already using C# any display application can just use the framework rather than needing its own message support.  And particular framework components can be graphical components without needing a separate display application.

Before doing so I decided to just get back to doing a graphical / display application once again.  That is, without worrying about the eXploratory Project framework.  To begin with I thought that I would try out WPF (Windows Presentation Foundation) in Visual Studio.

Visual Studio WPF

I went directly to the "I want to jump right in…" option of


to see how it went.  What I found was that it created xaml files with a little bit of C# code.  However, every time that the site directed me to do something it then directed me to replace what was produced with something else.  In doing all these replacements I goofed up on one occasion so that when I went to run the ExpenseIt application that was produced via the instructions an exception was raised when I tried to select one of its four people to display their expenses. 

I finally found that in doing the replacements and trying to get the xaml to be displayed better in the editor I had left a trailing piece of a line on the following line so that there was a double trailing '>' character.

This was the end of my WPF look see since I didn't see the point of attempting something that had so many steps where something would be generated just to have to modify it.  And where one little goof, without the ability to have a compiler available to flag it as an error, could force a person to have to examine the entire application to try to determine what might have gone wrong.

The WPF "jump right in" application ended up looking like this.
App.xaml
<Application x:Class="ExpenseIt.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>

        <!-- Header text style -->
        <Style x:Key="headerTextStyle">
            <Setter Property="Label.VerticalAlignment" Value="Center"></Setter>
            <Setter Property="Label.FontFamily" Value="Trebuchet MS"></Setter>
            <Setter Property="Label.FontWeight" Value="Bold"></Setter>
            <Setter Property="Label.FontSize" Value="18"></Setter>
            <Setter Property="Label.Foreground" Value="#0066cc"></Setter>
        </Style>

        <!-- Label style -->
        <Style x:Key="labelStyle" TargetType="{x:Type Label}">
            <Setter Property="VerticalAlignment" Value="Top" />
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="FontWeight" Value="Bold" />
            <Setter Property="Margin" Value="0,0,0,5" />
        </Style>

        <!-- DataGrid header style -->
        <Style x:Key="columnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
            <Setter Property="Height" Value="35" />
            <Setter Property="Padding" Value="5" />
            <Setter Property="Background" Value="#4E87D4" />
            <Setter Property="Foreground" Value="White" />
        </Style>

        <!-- List header style -->
        <Style x:Key="listHeaderStyle" TargetType="{x:Type Border}">
            <Setter Property="Height" Value="35" />
            <Setter Property="Padding" Value="5" />
            <Setter Property="Background" Value="#4E87D4" />
        </Style>

        <!-- List header text style -->
        <Style x:Key="listHeaderTextStyle" TargetType="{x:Type Label}">
            <Setter Property="Foreground" Value="White" />
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="HorizontalAlignment" Value="Left" />
        </Style>

        <!-- Button style -->
        <Style x:Key="buttonStyle" TargetType="{x:Type Button}">
            <Setter Property="Width" Value="125" />
            <Setter Property="Height" Value="25" />
            <Setter Property="Margin" Value="0,10,0,0" />
            <Setter Property="HorizontalAlignment" Value="Right" />
        </Style>

    </Application.Resources>
</Application>

MainWindow.xaml
<NavigationWindow x:Class="DisplayNorm.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500" Source="Form1.cs">

</NavigationWindow>

As I found out later, this is the xaml that displays the navigation bar for the window.

ExpenseItHome.xaml
<Page x:Class="ExpenseIt.ExpenseItHome"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      mc:Ignorable="d"
      d:DesignHeight="200" d:DesignWidth="300"
       Title="ExpenseIt - Home">

    <Grid>
        <Grid.Resources>
            <!-- Name item template -->
            <DataTemplate x:Key="nameItemTemplate">
                <Label Content="{Binding XPath=@Name}"/>
            </DataTemplate>
            <!-- Expense Report Data -->
            <XmlDataProvider x:Key="ExpenseDataSource" XPath="Expenses">
                <x:XData>
                    <Expenses xmlns="">
                        <Person Name="Mike" Department="Legal">
                            <Expense ExpenseType="Lunch" ExpenseAmount="50" />
                            <Expense ExpenseType="Transportation" ExpenseAmount="50" />
                        </Person>
                        <Person Name="Lisa" Department="Marketing">
                            <Expense ExpenseType="Document printing"
      ExpenseAmount="50"/>
                            <Expense ExpenseType="Gift" ExpenseAmount="125" />
                        </Person>
                        <Person Name="John" Department="Engineering">
                            <Expense ExpenseType="Magazine subscription"
     ExpenseAmount="50"/>
                            <Expense ExpenseType="New machine" ExpenseAmount="600" />
                            <Expense ExpenseType="Software" ExpenseAmount="500" />
                        </Person>
                        <Person Name="Mary" Department="Finance">
                            <Expense ExpenseType="Dinner" ExpenseAmount="100" />
                        </Person>
                    </Expenses>
                </x:XData>
            </XmlDataProvider>
        </Grid.Resources>
        <Grid.Background>
    <ImageBrush ImageSource="watermark.png"  />
</Grid.Background>

<Grid.ColumnDefinitions>
    <ColumnDefinition Width="230" />
    <ColumnDefinition />
</Grid.ColumnDefinitions>

<Grid.RowDefinitions>
    <RowDefinition/>
    <RowDefinition Height="Auto"/>
    <RowDefinition />
    <RowDefinition Height="Auto"/>
</Grid.RowDefinitions>

<!-- People list -->

<Label Grid.Column="1" Style="{StaticResource headerTextStyle}" >
    View Expense Report
</Label>

<Border Grid.Column="1" Grid.Row="1" Style="{StaticResource listHeaderStyle}">
    <Label Style="{StaticResource listHeaderTextStyle}">Names</Label>
</Border>
<ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2"
         ItemsSource="{Binding Source={StaticResource ExpenseDataSource}, XPath=Person}"
         ItemTemplate="{StaticResource nameItemTemplate}">
</ListBox>
<!-- View report button -->
<Button Grid.Column="1" Grid.Row="3" Margin="0,10,0,0" Width="125"
Height="25" HorizontalAlignment="Right" Click="Button_Click">View</Button>
    </Grid>
</Page>

ExpenseItHome.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ExpenseIt
{
    /// <summary>
    /// Interaction logic for ExpenseItHome.xaml
    /// </summary>
    public partial class ExpenseItHome : Page
    {
        public ExpenseItHome()
        {
            InitializeComponent();
        }
       
        {
            Console.WriteLine("Event {0}",e);
            Object o = (Object)x;  // o is Person
            Type t = o.GetType();  // t is FullName
            var n = t.Name;        // n is xmlElement
            var m = t.FullName;    // System.xml.xmlElement
            // View Expense Report
            ExpenseReportPage expenseReportPage = new ExpenseReportPage(this.peopleListBox.SelectedItem);
            this.NavigationService.Navigate(expenseReportPage);

        }

        void NavigationService_Navigated(object sender, NavigationEventArgs e)
        {
            string msg = string.Format("Downloading {0}.", e.Uri.OriginalString);
        }
    }
}
where the five lines above "// View Expense Report" were added by me to see what they might result in.  The comment that follows each is what appears when hover over it in the debugger.

ExpenseReportPage.xaml

<Page x:Class="ExpenseIt.ExpenseReportPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      mc:Ignorable="d"
      d:DesignHeight="300" d:DesignWidth="300"
       Title="ExpenseIt - View Expense">

    <Grid>
        <!--Templates to display expense report data-->
        <Grid.Resources>
            <!-- Reason item template -->
            <DataTemplate x:Key="typeItemTemplate">
                <Label Content="{Binding XPath=@ExpenseType}"/>
            </DataTemplate>
            <!-- Amount item template -->
            <DataTemplate x:Key="amountItemTemplate">
                <Label Content="{Binding XPath=@ExpenseAmount}"/>
            </DataTemplate>
        </Grid.Resources>
        <Grid.Background>
            <ImageBrush ImageSource="watermark.png" />
        </Grid.Background>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="230" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>


        <Label Grid.Column="1" Style="{StaticResource headerTextStyle}">
            Expense Report For:
        </Label>
        <Grid Margin="10" Grid.Column="1" Grid.Row="1">

            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition />
            </Grid.RowDefinitions>

            <!-- Name -->
            <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Orientation="Horizontal">
                <Label Style="{StaticResource labelStyle}">Name:</Label>
                <Label Style="{StaticResource labelStyle}" Content="{Binding XPath=@Name}"></Label>
            </StackPanel>

            <!-- Department -->
            <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1"
Orientation="Horizontal">
                <Label Style="{StaticResource labelStyle}">Department:</Label>
                <Label Style="{StaticResource labelStyle}" Content="{Binding XPath=@Department}"></Label>
            </StackPanel>

            <Grid Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" VerticalAlignment="Top"
          HorizontalAlignment="Left">
                <!-- Expense type and Amount table -->
                <DataGrid ItemsSource="{Binding XPath=Expense}" ColumnHeaderStyle="{StaticResource columnHeaderStyle}" AutoGenerateColumns="False" RowHeaderWidth="0" >
                    <DataGrid.Columns>
                        <DataGridTextColumn Header="ExpenseType" Binding="{Binding XPath=@ExpenseType}" />
                        <DataGridTextColumn Header="Amount" Binding="{Binding XPath=@ExpenseAmount}" />
                    </DataGrid.Columns>
                </DataGrid>
            </Grid>
        </Grid>
    </Grid>
</Page>

ExpenseReportPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ExpenseIt
{
    /// <summary>
    /// Interaction logic for ExpenseReportPage.xaml
    /// </summary>
    public partial class ExpenseReportPage : Page
    {
        public ExpenseReportPage()
        {
            InitializeComponent();
        }
       
        // Custom constructor to pass expense report data
        public ExpenseReportPage(object data):this()
        {
            // Bind to expense report data.
            this.DataContext = data;
        }

    }
}


Where the mouse highlighted Lisa and
when the View button was clicked.

The navigation bar at the top went back and forth between the two pages.  When going from the first page to the second, the last previously selected Name is displayed. 

Visual Studio C#

So I then set about to duplicate the "jump right in" application in C# without the use of WPF.

I created 2 forms, one for each view.  For some reason I could place the controls (widgets) on form1 but not form2 so had to guess at what their placement should be and then correct it until it was satisfactory.

Since I couldn't determine how to put a navigation bar on a form I used a panel and used Jing to capture the arrow images from the xaml display. 

I also couldn't determine how to just display text such as Expense Report For:, Name:, Lisa, Department: and Marketing.  I searched for how to display a label or text box with a transparent background or no boundary but without success.  I found RenderTransparent for a label but it is now obsolete and couldn't be used.  I did determine how to display a background image and a button image.

I found the example
public void DrawString()
{
    System.Drawing.Graphics formGraphics = this.CreateGraphics();
    string drawString = "Sample Text";
    System.Drawing.Font drawFont = new System.Drawing.Font("Arial", 16);
    System.Drawing.SolidBrush drawBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Black);
    float x = 150.0F;
    float y = 50.0F;
    System.Drawing.StringFormat drawFormat = new System.Drawing.StringFormat();
    formGraphics.DrawString(drawString, drawFont, drawBrush, x, y, drawFormat);
    drawFont.Dispose();
    drawBrush.Dispose();
    formGraphics.Dispose();
}
but when I tried it nothing appeared even when I reduced the x,y position.

Using just C# the forms display as

and


I also put in to have the View button display with a red background when hovered over.

As displayed, Form2 displays along with Form1 since I didn't bother to hide Form1 when Form2 was displayed.

By making the forms wider, the ExpenseType list box could be made wider, as it is in the WPF version, so that the complete text would display in all cases.  Although easy enough to do, I left the forms as I first created them since I didn't feel that this was the object of the exercise.

I copied Form1.Designer.cs InitializeComponent into Form1.cs when I was having trouble getting Form2 to display.  This was because, for a while, the Form1 constructor repeated over and over until the application was out of memory.  So, in the following code, InitializeComponent is in Form1.cs.

Program.cs

As generated by C#
sing System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

Resources.Designer.cs

As generated by C#
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace WindowsFormsApplication1.Properties {
    using System;
   
   
    /// <summary>
    ///   A strongly-typed resource class, for looking up localized strings, etc.
    /// </summary>
    // This class was auto-generated by the StronglyTypedResourceBuilder
    // class via a tool like ResGen or Visual Studio.
    // To add or remove a member, edit your .ResX file then rerun ResGen
    // with the /str option, or rebuild your VS project.
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    internal class Resources {
       
        private static global::System.Resources.ResourceManager resourceMan;
       
        private static global::System.Globalization.CultureInfo resourceCulture;
       
        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal Resources() {
        }
       
        /// <summary>
        ///   Returns the cached ResourceManager instance used by this class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Resources.ResourceManager ResourceManager {
            get {
                if (object.ReferenceEquals(resourceMan, null)) {
                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WindowsFormsApplication1.Properties.Resources", typeof(Resources).Assembly);
                    resourceMan = temp;
                }
                return resourceMan;
            }
        }
       
        /// <summary>
        ///   Overrides the current thread's CurrentUICulture property for all
        ///   resource lookups using this strongly typed resource class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Globalization.CultureInfo Culture {
            get {
                return resourceCulture;
            }
            set {
                resourceCulture = value;
            }
        }
       
        /// <summary>
        ///   Looks up a localized resource of type System.Drawing.Bitmap.
        /// </summary>
        internal static System.Drawing.Bitmap LeftArrow {
            get {
                object obj = ResourceManager.GetObject("LeftArrow", resourceCulture);
                return ((System.Drawing.Bitmap)(obj));
            }
        }
       
        /// <summary>
        ///   Looks up a localized resource of type System.Drawing.Bitmap.
        /// </summary>
        internal static System.Drawing.Bitmap RightArrow {
            get {
                object obj = ResourceManager.GetObject("RightArrow", resourceCulture);
                return ((System.Drawing.Bitmap)(obj));
            }
        }
    }
}

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Image leftArrowImage;
        public Image leftArrowGrayedImage;
        public Image rightArrowImage;
        public Image rightArrowGrayedImage;

        Form2 secondForm;

        bool initialize;
        string personSelected = "";

        public Form1()
        {
            initialize = true;
            if (initialize)
            {
                this.textBox1 = new System.Windows.Forms.TextBox();
                this.listBox1 = new System.Windows.Forms.ListBox();
                this.label2 = new System.Windows.Forms.Label();
                this.button1 = new System.Windows.Forms.Button();
                this.panel1 = new System.Windows.Forms.Panel();
                this.button3 = new System.Windows.Forms.Button();
                this.button2 = new System.Windows.Forms.Button();
                this.panel1.SuspendLayout();
                this.SuspendLayout();
                //
                // textBox1
                //
                this.textBox1.BackColor = System.Drawing.SystemColors.MenuHighlight;
                this.textBox1.Location = new System.Drawing.Point(150, 87);
                this.textBox1.Name = "textBox1";
                this.textBox1.Size = new System.Drawing.Size(120, 22);
                this.textBox1.TabIndex = 3;
                this.textBox1.Text = "Names";
                //
                // listBox1
                //
                this.listBox1.FormattingEnabled = true;
                this.listBox1.ItemHeight = 16;
                this.listBox1.Location = new System.Drawing.Point(150, 107);
                this.listBox1.Name = "listBox1";
                this.listBox1.Size = new System.Drawing.Size(120, 84);
                this.listBox1.TabIndex = 4;
                //
                // label2
                //
                this.label2.AutoSize = true;
                this.label2.ForeColor = System.Drawing.SystemColors.HotTrack;
                this.label2.Location = new System.Drawing.Point(138, 54);
                this.label2.Name = "label2";
                this.label2.Size = new System.Drawing.Size(142, 17);
                this.label2.TabIndex = 6;
                this.label2.Text = "View Expense Report";
                //
                // button1
                //
                this.button1.Location = new System.Drawing.Point(150, 221);
                this.button1.Name = "button1";
                this.button1.Size = new System.Drawing.Size(120, 30);
                this.button1.TabIndex = 7;
                this.button1.Text = "View";
                this.button1.UseVisualStyleBackColor = true;
                //
                // panel1
                //
                this.panel1.Controls.Add(this.button3);
                this.panel1.Controls.Add(this.button2);
                this.panel1.Location = new System.Drawing.Point(-2, 0);
                this.panel1.Name = "panel1";
                this.panel1.Size = new System.Drawing.Size(282, 42);
                this.panel1.TabIndex = 8;
                //
                // button3
                //
                this.button3.Image = global::WindowsFormsApplication1.Properties.Resources.RightArrow;
                this.button3.Location = new System.Drawing.Point(38, 3);
                this.button3.Name = "button3";
                this.button3.Size = new System.Drawing.Size(36, 36);
                this.button3.TabIndex = 1;
                this.button3.UseVisualStyleBackColor = true;
                //
                // button2
                //
                this.button2.BackColor = System.Drawing.SystemColors.ButtonHighlight;
                this.button2.ForeColor = System.Drawing.SystemColors.ControlLightLight;
                this.button2.Image = global::WindowsFormsApplication1.Properties.Resources.LeftArrow;
                this.button2.Location = new System.Drawing.Point(3, 3);
                this.button2.Name = "button2";
                this.button2.Size = new System.Drawing.Size(36, 36);
                this.button2.TabIndex = 0;
                this.button2.UseVisualStyleBackColor = false;
                //
                // Form1
                //
                this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(282, 253);
                this.Controls.Add(this.panel1);
                this.Controls.Add(this.button1);
                this.Controls.Add(this.label2);
                this.Controls.Add(this.listBox1);
                this.Controls.Add(this.textBox1);
                this.Name = "Form1";
                this.Text = "ExpenseIt";
                this.panel1.ResumeLayout(false);
                this.ResumeLayout(false);
                this.PerformLayout();

                if (initialize)
                {
                    initialize = false;
                    ContinueInitialize();
                }

            }

         } // end Form1 constructor

        private void ContinueInitialize()
        {
            // Assign a background image.
            Image newImage = Image.FromFile("C:\\Source\\XP-Display\\ExpenseIt\\watermark.png");
            this.BackgroundImage = newImage;
            this.BackgroundImageLayout = ImageLayout.Stretch;


            this.button1.Click += new System.EventHandler(this.button1_Click);
            this.button1.MouseLeave += new System.EventHandler(this.button1_MouseLeave);
            this.button1.MouseHover += new System.EventHandler(this.button1_MouseHover);

            // Note: Normally would get from a database.
            this.listBox1.Items.Add("Mike");
            this.listBox1.Items.Add("Lisa");
            this.listBox1.Items.Add("John");
            this.listBox1.Items.Add("Mary");
            this.listBox1.Height = listBox1.PreferredHeight;

            this.listBox1.SelectionMode = SelectionMode.One;
            this.listBox1.Click += new EventHandler(this.listBox1_Click);

            leftArrowImage = Image.FromFile("C:\\Source\\XP-Display\\LeftArrow.png");
            leftArrowGrayedImage = Image.FromFile("C:\\Source\\XP-Display\\LeftArrowGrayed.png");
            rightArrowImage = Image.FromFile("C:\\Source\\XP-Display\\RightArrow.png");
            rightArrowGrayedImage = Image.FromFile("C:\\Source\\XP-Display\\RightArrowGrayed.png");

            this.button2.Image = leftArrowGrayedImage;
            this.button3.Image = rightArrowImage;

            this.button2.Click += new System.EventHandler(this.button2_Click);
            this.button3.Click += new System.EventHandler(this.button3_Click);
        } // end ContinueInialize

        string tentativePersonSelected = "";
        private void listBox1_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 4; i++)
            {
                bool selected = listBox1.GetSelected(i);
                if (selected)
                {
                    tentativePersonSelected = listBox1.SelectedItem.ToString();
                    // treat person selected when View clicked
                    break; // exit
                }
            }

        } // end listBox1_Click

        private void button1_Click(object sender, EventArgs e)
        {
            if (tentativePersonSelected != "")
            {
                personSelected = tentativePersonSelected;
                // Switch to ExpenseReport form
                if (secondForm == null)
                {
                    secondForm = new Form2(this); //, personSelected);
                }
                secondForm.setSelectedPerson(personSelected);
                secondForm.Show();
            }

        } // end button1_Click
   
        private void button1_MouseHover(object sender, EventArgs e)
        {
            Color trnsRed = Color.FromArgb(255, 255, 0, 0);
            this.button1.BackColor = trnsRed;
        } // end button1_MouseHover

        private void button1_MouseLeave(object sender, EventArgs e)
        {
            Color trnsxxx = Color.FromArgb(120, 255, 255, 255);
            this.button1.BackColor = trnsxxx;
        } // button1_MouseLeave

        private void button2_Click(object sender, EventArgs e)
        {
            if (this.button2.Image == leftArrowImage)
            {
                this.button2.Image = leftArrowGrayedImage;
                this.button3.Image = rightArrowImage;

                // hide the other form
                secondForm.Hide();
            }
        } // end button2_Click

        private void button3_Click(object sender, EventArgs e)
        {
            if (this.button3.Image == rightArrowImage)
            {
                this.button2.Image = leftArrowImage;
                //     this.button3.Enabled = true;
                this.button3.Image = rightArrowGrayedImage;
                //     this.button3.Enabled = false;

                // switch to form2
                if (secondForm == null)
                {
                    secondForm = new Form2(this); //, "");
                    secondForm.setSelectedPerson("");
                    secondForm.Show();
                }
                else
                {
                    secondForm.setSelectedPerson(personSelected);
                    secondForm.Show();
                }
            }
            // else ignore the click
        } // end button3_Click

    } // end class Form1
} // end namespace

Form2.cs

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{

    public partial class Form2 : Form
    {
        Image leftArrowImage;
        Image leftArrowGrayedImage;
        Image rightArrowImage;
        Image rightArrowGrayedImage;

        Panel panel1;

        Button button2;
        Button button3;

        Label label1;
        Label label2;
        Label label3;
        TextBox textBox1;
        TextBox textBox2;
        TextBox textBox3;
        ListBox listBox1;
        ListBox listBox2;

        Form firstForm = new Form1();

        string selectedPerson;

        struct PersonDataArray
        {
            public string ExpenseType;
            public int Amount;
        }
        class PersonDataListType
        {
            public string Name;
            public string Department;
            public int Count;
            public PersonDataArray[] Data = new PersonDataArray[4];
        }
        PersonDataListType[] expenses = new PersonDataListType[4];

        void setExpenses()
        {
            expenses[0] = new PersonDataListType();
            expenses[0].Name = "Mike";
            expenses[0].Department = "Legal";
            expenses[0].Data[0].ExpenseType = "Lunch";
            expenses[0].Data[0].Amount = 50;
            expenses[0].Data[1].ExpenseType = "Transportation";
            expenses[0].Data[1].Amount = 50;
            expenses[0].Count = 2;
            expenses[1] = new PersonDataListType();
            expenses[1].Name = "Lisa";
            expenses[1].Department = "Marketing";
            expenses[1].Data[0].ExpenseType = "Document printing";
            expenses[1].Data[0].Amount = 50;
            expenses[1].Data[1].ExpenseType = "Gift";
            expenses[1].Data[1].Amount = 125;
            expenses[1].Count = 2;
            expenses[2] = new PersonDataListType();
            expenses[2].Name = "John";
            expenses[2].Department = "Engineering";
            expenses[2].Data[0].ExpenseType = "Magazine subscription";
            expenses[2].Data[0].Amount = 50;
            expenses[2].Data[1].ExpenseType = "New machine";
            expenses[2].Data[1].Amount = 600;
            expenses[2].Data[2].ExpenseType = "Software";
            expenses[2].Data[2].Amount = 500;
            expenses[2].Count = 3;
            expenses[3] = new PersonDataListType();
            expenses[3].Name = "Mary";
            expenses[3].Department = "Finance";
            expenses[3].Data[0].ExpenseType = "Dinner";
            expenses[3].Data[0].Amount = 100;
            expenses[3].Count = 1;
        }

        public Form2(Form formOne)
        {
            panel1 = new System.Windows.Forms.Panel();
            button3 = new System.Windows.Forms.Button();
            button2 = new System.Windows.Forms.Button();
            panel1.SuspendLayout();

            leftArrowImage = Image.FromFile("C:\\Source\\XP-Display\\LeftArrow.png");
            leftArrowGrayedImage = Image.FromFile("C:\\Source\\XP-Display\\LeftArrowGrayed.png");
            rightArrowImage = Image.FromFile("C:\\Source\\XP-Display\\RightArrow.png");
            rightArrowGrayedImage = Image.FromFile("C:\\Source\\XP-Display\\RightArrowGrayed.png");
          
            label1 = new System.Windows.Forms.Label();
            label2 = new System.Windows.Forms.Label();
            label3 = new System.Windows.Forms.Label();
            textBox1 = new TextBox();
            textBox2 = new TextBox();
            textBox3 = new TextBox();
            listBox1 = new System.Windows.Forms.ListBox();
            listBox2 = new System.Windows.Forms.ListBox();

            SuspendLayout();
            Initialize();

            // Assign a background image.
            Image newImage = Image.FromFile("C:\\Source\\XP-Display\\ExpenseIt\\watermark.png");
            this.BackgroundImage = newImage;
            this.BackgroundImageLayout = ImageLayout.Stretch;

            this.button2.Image = leftArrowImage;
            this.button3.Image = rightArrowGrayedImage;

            this.ResumeLayout(false);
            this.PerformLayout();

            setExpenses();
        }

        private void Initialize()
        {
            //
            // panel1
            //
            this.panel1.Controls.Add(this.button3);
            this.panel1.Controls.Add(this.button2);
            this.panel1.Location = new System.Drawing.Point(-2, 0);
            this.panel1.Name = "panel1";
            this.panel1.Size = new System.Drawing.Size(282, 42);
            this.panel1.TabIndex = 8;
            //
            // button2
            //
            this.button2.BackColor = System.Drawing.SystemColors.ButtonHighlight;
            this.button2.ForeColor = System.Drawing.SystemColors.ControlLightLight;
            this.button2.Image = global::WindowsFormsApplication1.Properties.Resources.LeftArrow;
            this.button2.Location = new System.Drawing.Point(3, 3);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(36, 36);
            this.button2.TabIndex = 0;
            this.button2.UseVisualStyleBackColor = false;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            //
            // button3
            //
            this.button3.Image = global::WindowsFormsApplication1.Properties.Resources.RightArrow;
            this.button3.Location = new System.Drawing.Point(38, 3);
            this.button3.Name = "button3";
            this.button3.Size = new System.Drawing.Size(36, 36);
            this.button3.TabIndex = 1;
            this.button3.UseVisualStyleBackColor = true;
            this.button3.Click += new System.EventHandler(this.button3_Click);

            this.label1.AutoSize = true;
            this.label1.ForeColor = System.Drawing.SystemColors.HotTrack;
            this.label1.Location = new System.Drawing.Point(95, 55);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(146, 17);
            this.label1.Text = "Expense Account For:";
            //
            // label2
            //
            this.label2.AutoSize = true;
            this.label2.ForeColor = System.Drawing.SystemColors.HotTrack;
            this.label2.Location = new System.Drawing.Point(95, 91);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(46, 17);
            this.label2.Text = "Name:";
            //
            // label3
            //
            this.label3.AutoSize = true;
            this.label3.ForeColor = System.Drawing.SystemColors.HotTrack;
            this.label3.Location = new System.Drawing.Point(95, 122);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(76, 17);
            this.label3.Text = "Department:";
            //
            // textBox1
            //
            this.textBox1.BackColor = System.Drawing.SystemColors.MenuHighlight;
            this.textBox1.Location = new System.Drawing.Point(150, 89);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(125, 17);
            this.textBox1.Text = selectedPerson; // "";
            this.textBox1.BorderStyle = BorderStyle.None;
            //
            // textBox2
            //
            this.textBox2.BackColor = System.Drawing.SystemColors.MenuHighlight;
            this.textBox2.Location = new System.Drawing.Point(184, 120);
            this.textBox2.Name = "textBox2";
            this.textBox2.Size = new System.Drawing.Size(90, 17);
            this.textBox2.Text = "";
            //
            // textBox3
            //
            this.textBox3.BackColor = System.Drawing.SystemColors.MenuHighlight;
            this.textBox3.Location = new System.Drawing.Point(95, 152);
            this.textBox3.Name = "textBox3";
            this.textBox3.Size = new System.Drawing.Size(180, 17);
            this.textBox3.Text = "ExpenseType   Amount";
            //
            // listBox1
            //
            this.listBox1.FormattingEnabled = true;
            this.listBox1.ItemHeight = 16;
            this.listBox1.Location = new System.Drawing.Point(95, 171);
            this.listBox1.Name = "listBox1";
            this.listBox1.Size = new System.Drawing.Size(90, 68);
            //
            // listBox2
            //
            this.listBox2.FormattingEnabled = true;
            this.listBox2.ItemHeight = 16;
            this.listBox2.Location = new System.Drawing.Point(185, 171);
            this.listBox2.Name = "listBox2";
            this.listBox2.Size = new System.Drawing.Size(90, 68);

            //
            // Form2
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(282, 253);
            this.Controls.Add(this.panel1);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.textBox2);
            this.Controls.Add(this.textBox3);
            this.Controls.Add(this.listBox1);
            this.Controls.Add(this.listBox2);

            this.Name = "Form2";
            this.Text = "ExpenseIt";
            this.panel1.ResumeLayout(false);
        } // end Initialize

        public void setSelectedPerson(string personSelected)
        {
            selectedPerson = personSelected;
            this.textBox1.Text = selectedPerson;
            this.button2.Image = leftArrowImage;
            this.button3.Image = rightArrowGrayedImage;

            if (selectedPerson != "")
            {
                for (int i = 0; i < 4; i++)
                {
                    if (selectedPerson == expenses[i].Name)
                    {
                        textBox2.Text = expenses[i].Department;
                        listBox1.Items.Clear();
                        listBox2.Items.Clear();
                        for (int l = 0; l < expenses[i].Count; l++)
                        {
                            listBox1.Items.Add(expenses[i].Data[l].ExpenseType);
                            listBox2.Items.Add(expenses[i].Data[l].Amount);
                        }
                        listBox1.Height = listBox1.PreferredHeight;
                        listBox2.Height = listBox2.PreferredHeight;
                        break; // exit loop
                    }
                }
            }
            this.Update();
        } // end setSelectedPerson

        private void button2_Click(object sender, System.EventArgs e)
        {
            if (this.button2.Image == leftArrowImage)
            {
                this.button2.Image = leftArrowGrayedImage;
                this.button3.Image = rightArrowImage;

                // switch to other form
                this.Hide();
            }
        } // end button2_Click

        private void button3_Click(object sender, System.EventArgs e)
        {
            if (this.button3.Image == rightArrowImage)
            {
                this.button2.Image = leftArrowImage;
                this.button3.Image = rightArrowGrayedImage;

                // switch to form2
                this.Show();
            }
            // else ignore the click
        } // end button3_Click

    } // end class Form2
}

Of course neither the WPF example of the https://docs.microsoft.com/en-us/dotnet/framework/wpf/getting-started/ web site nor the attempt to duplicate it with just C# represent a real application since both have the data to be displayed canned within the xaml in the one case and in the .cs code in the second.

What I would like to discover is how to create a window with the navigation bar and how to do it in C#.  Being able to display text without a label or textbox could be nice but not a priority.

I looked further into the use of declaring a MainWindow class via
   class MainWindow : System.Windows.Navigation.NavigationWindow
with an attempt to allow C# to place the controls.  But I had no success.  I could get the NavigationBar if I included the NavigationWindow xaml and I could create controls in the cs file but I couldn't get them to display on the window.  All I was able to do was to create a form which then displayed separately from the MainWindow.


No comments: