Universal Windows Platform – Matrix Control

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu locate and select Visual Studio 2017.

vs2017-home

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project

vs2017-new-project

Step 4

Then in New Universal Windows Project you need to select the Target Version to be Windows 10 Creators Update (10.0; Build 15063) and the Minimum Version to be at least Windows 10 Anniversary Update (10.0; Build 14393) or Windows 10 Creators Update (10.0; Build 15063)

vs2017-platform

Step 5

From the Menu choose Project, then Add New Item…

vs2017-add-new-item

Step 6

From the Add New Item choose Visual C# from Installed then choose XAML then select User Control and then in the Name as Matrix.xaml and then select Add to add the file to the Project

user-matrix-control

Step 7

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Viewbox>
	<Grid Name="Display"/>
</Viewbox>

It should appear as such:

xaml-user-matrix-control

Step 8

From the Menu choose View and then Code

vs2017-view-code

Step 9

Once in the Code View, below the public Matrix() { … } the following Code should be entered:

private readonly byte[][] table =
{
	new byte[] {
	0,0,0,0,0,0,0,0,
	0,1,1,1,1,1,1,0,
	0,1,1,0,0,1,1,0,
	0,1,1,0,0,1,1,0,
	0,1,1,0,0,1,1,0,
	0,1,1,1,1,1,1,0,
	0,0,0,0,0,0,0,0
	}, // 0
	new byte[] {
	0,0,0,0,0,0,0,0,
	0,0,0,1,1,0,0,0,
	0,1,1,1,1,0,0,0,
	0,0,0,1,1,0,0,0,
	0,0,0,1,1,0,0,0,
	0,0,0,1,1,0,0,0,
	0,0,0,0,0,0,0,0
	}, // 1 
	new byte[] {
	0,0,0,0,0,0,0,0,
	0,1,1,1,1,1,1,0,
	0,0,0,0,0,1,1,0,
	0,1,1,1,1,1,1,0,
	0,1,1,0,0,0,0,0,
	0,1,1,1,1,1,1,0,
	0,0,0,0,0,0,0,0
	}, // 2
	new byte[] {
	0,0,0,0,0,0,0,0,
	0,1,1,1,1,1,1,0,
	0,0,0,0,0,1,1,0,
	0,1,1,1,1,1,1,0,
	0,0,0,0,0,1,1,0,
	0,1,1,1,1,1,1,0,
	0,0,0,0,0,0,0,0
	}, // 3
	new byte[] {
	0,0,0,0,0,0,0,0,
	0,1,1,0,0,1,1,0,
	0,1,1,0,0,1,1,0,
	0,1,1,1,1,1,1,0,
	0,0,0,0,0,1,1,0,
	0,0,0,0,0,1,1,0,
	0,0,0,0,0,0,0,0
	}, // 4
	new byte[] {
	0,0,0,0,0,0,0,0,
	0,1,1,1,1,1,1,0,
	0,1,1,0,0,0,0,0,
	0,1,1,1,1,1,1,0,
	0,0,0,0,0,1,1,0,
	0,1,1,1,1,1,1,0,
	0,0,0,0,0,0,0,0
	}, // 5
	new byte[] {
	0,0,0,0,0,0,0,0,
	0,1,1,1,1,1,1,0,
	0,1,1,0,0,0,0,0,
	0,1,1,1,1,1,1,0,
	0,1,1,0,0,1,1,0,
	0,1,1,1,1,1,1,0,
	0,0,0,0,0,0,0,0
	}, // 6
	new byte[] {
	0,0,0,0,0,0,0,0,
	0,1,1,1,1,1,1,0,
	0,0,0,0,0,1,1,0,
	0,0,0,0,0,1,1,0,
	0,0,0,0,0,1,1,0,
	0,0,0,0,0,1,1,0,
	0,0,0,0,0,0,0,0
	}, // 7
	new byte[] {
	0,0,0,0,0,0,0,0,
	0,1,1,1,1,1,1,0,
	0,1,1,0,0,1,1,0,
	0,1,1,1,1,1,1,0,
	0,1,1,0,0,1,1,0,
	0,1,1,1,1,1,1,0,
	0,0,0,0,0,0,0,0
	}, // 8
	new byte[] {
	0,0,0,0,0,0,0,0,
	0,1,1,1,1,1,1,0,
	0,1,1,0,0,1,1,0,
	0,1,1,1,1,1,1,0,
	0,0,0,0,0,1,1,0,
	0,1,1,1,1,1,1,0,
	0,0,0,0,0,0,0,0
	}, // 9
	new byte[] {
	0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0
	}, // None
	new byte[] {
	0,0,0,0,0,0,0,0,
	0,0,0,1,1,0,0,0,
	0,0,0,1,1,0,0,0,
	0,0,0,0,0,0,0,0,
	0,0,0,1,1,0,0,0,
	0,0,0,1,1,0,0,0,
	0,0,0,0,0,0,0,0
	}, // Colon
	new byte[] {
	0,0,0,0,0,0,0,0,
	0,0,0,0,0,1,1,0,
	0,0,0,0,1,1,0,0,
	0,0,0,1,1,0,0,0,
	0,0,1,1,0,0,0,0,
	0,1,1,0,0,0,0,0,
	0,0,0,0,0,0,0,0
	} // Slash
};
private readonly List<char> symbols =
	new List<char> { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' ', ':', '/' };
private const int columns = 8;
private const int rows = 7;
private const int size = 10;
private byte[,] board = null;
private int count = 0;
private string _output = string.Empty;

private byte[,] AsTwoDimensionalArray(byte[] input, int height, int width)
{
	byte[,] output = new byte[height, width];
	for (int r = 0; r < height; r++)
	{
		for (int c = 0; c < width; c++)
		{
			output[r, c] = input[r * width + c];
		}
	}
	return output;
}

private int SetBoard(char[] characters)
{
	int length = characters.Count();
	board = new byte[rows, (columns * length)];
	int offset = 0;
	foreach (char character in characters)
	{
		int index = symbols.IndexOf(character);
		byte[,] symbol = AsTwoDimensionalArray(table[index], rows, columns);
		for (int row = 0; row < rows; row++)
		{
			for (int column = 0; column < columns; column++)
			{
				board[row, column + offset] = symbol[row, column];
			}
		}
		offset += columns;
	}
	return length;
}

private Windows.UI.Xaml.Shapes.Rectangle GetPixel(int row, int column)
{
	Windows.UI.Xaml.Shapes.Rectangle rect = 
		new Windows.UI.Xaml.Shapes.Rectangle()
	{
		Height = size,
		Width = size,
		Fill = Foreground,
		RadiusX = 2,
		RadiusY = 2,
		Opacity = 0,
		Margin = new Thickness(2)
	};
	rect.SetValue(Grid.ColumnProperty, column);
	rect.SetValue(Grid.RowProperty, row);
	return rect;
}

private void Setup()
{
	for (int row = 0; row < board.GetLength(0); row++)
	{
		for (int column = 0; column < board.GetLength(1); column++)
		{
			Windows.UI.Xaml.Shapes.Rectangle rect = 
				Display.Children.Cast<Windows.UI.Xaml.Shapes.Rectangle>()
				.FirstOrDefault(
				f => Grid.GetRow(f) == row 
				&& Grid.GetColumn(f) == column);
			rect.Opacity = board[row, column];
		}
	}
}

private void Layout(int length)
{
	int total = (columns * length);
	Display.Children.Clear();
	Display.RowDefinitions.Clear();
	Display.ColumnDefinitions.Clear();
	// Grid
	for (int row = 0; row < rows; row++)
	{
		Display.RowDefinitions.Add(new RowDefinition());
	}
	for (int column = 0; column < total; column++)
	{
		Display.ColumnDefinitions.Add(new ColumnDefinition());
	}
	// Layout
	for (int row = 0; row < rows; row++)
	{
		for (int column = 0; column < total; column++)
		{
			Display.Children.Add(GetPixel(row, column));
		}
	}
	Display.Height = Display.RowDefinitions.Count() * (size + 10);
	Display.Width = (Display.ColumnDefinitions.Count() * (size + 20)) / 2;
}

private void SetOutput(string content)
{
	char[] characters = content.ToCharArray();
	int length = SetBoard(characters);
	if (characters.Length != count)
	{
		Layout(characters.Length);
	}
	Setup();
}

public string Output
{
	get { return _output; }
	set
	{
		if (_output != value)
		{
			_output = value;
			SetOutput(_output);
		}
	}
}

Step 10

From the Menu choose Build and then Build Solution

vs2017-build

Step 11

Then in the Solution Explorer select MainPage.xaml

vs2017-library-mainpage

Step 12

From the Menu choose View and then Designer

vs2017-view-designer

Step 13

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<local:Matrix x:Name="Display" HorizontalAlignment="Center" VerticalAlignment="Center"  Margin="50" Foreground="{ThemeResource AccentButtonBackground}" Loaded="Display_Loaded"/>

It should appear as such:

xaml-matrix-control

Step 14

From the Menu choose View and then Code

vs2017-view-code

Step 15

Once in the Code View, below the public MainPage() { … } the following Code should be entered:

private void Display_Loaded(object sender, RoutedEventArgs e)
{
	int count = 0;
	DispatcherTimer timer = new DispatcherTimer()
	{
		Interval = TimeSpan.FromMilliseconds(100)
	};
	timer.Tick += (object s, object args) =>
	{
		if (count > 150) count = 0;
		string format = (count < 100) ? "HH:mm:ss" : "dd/MM/yyyy";
		Display.Output = DateTime.Now.ToString(format);
		count++;
	};
	timer.Start();
}

It should then appear as such:

code-matrix-control

Step 16

That completes the Universal Windows Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-debug

Step 17

Once started the Application should then appear displaying a Matrix based Clock that will also alternate to show Time and then Date

run-matrix-control

Step 18

To Exit the application select Stop in Visual Studio

vs2017-stop

Creative Commons License

Universal Windows Platform – Custom ComboBox

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu locate and select Visual Studio 2017.

vs2017-home

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project

vs2017-new-project

Step 4

Then in New Universal Windows Project you need to select the Target Version to be Windows 10 Creators Update (10.0; Build 15063) and the Minimum Version to be at least Windows 10 Anniversary Update (10.0; Build 14393) or Windows 10 Creators Update (10.0; Build 15063)

vs2017-platform

Step 5

In the Solution Explorer select App.xaml

vs2017-app

Step 6

From the Menu choose View and then Designer

vs2017-view-designer

Step 7

The XAML View and in this between the Application and /Application elements, enter the following XAML:

<Application.Resources>
	<Style x:Key="CustomComboBox" TargetType="ComboBox">
		<Setter Property="Padding" Value="12,5,0,7"/>
		<Setter Property="MinWidth" Value="{ThemeResource ComboBoxThemeMinWidth}"/>
		<Setter Property="Foreground" Value="Gold"/>
		<Setter Property="Background" Value="{ThemeResource ComboBoxBackground}"/>
		<Setter Property="BorderBrush" Value="{ThemeResource ComboBoxBorderBrush}"/>
		<Setter Property="BorderThickness" Value="{ThemeResource ComboBoxBorderThemeThickness}"/>
		<Setter Property="TabNavigation" Value="Once"/>
		<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
		<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
		<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled"/>
		<Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto"/>
		<Setter Property="ScrollViewer.IsVerticalRailEnabled" Value="True"/>
		<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False"/>
		<Setter Property="ScrollViewer.BringIntoViewOnFocusChange" Value="True"/>
		<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
		<Setter Property="HorizontalAlignment" Value="Left"/>
		<Setter Property="VerticalAlignment" Value="Top"/>
		<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
		<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
		<Setter Property="ItemsPanel">
			<Setter.Value>
				<ItemsPanelTemplate>
					<CarouselPanel/>
				</ItemsPanelTemplate>
			</Setter.Value>
		</Setter>
		<Setter Property="Template">
			<Setter.Value>
				<ControlTemplate TargetType="ComboBox">
					<Grid x:Name="LayoutRoot">
						<Grid.Resources>
							<Storyboard x:Key="OverlayOpeningAnimation">
								<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity">
									<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="0.0"/>
									<SplineDoubleKeyFrame KeySpline="0.1,0.9 0.2,1.0" KeyTime="0:0:0.383" Value="1.0"/>
								</DoubleAnimationUsingKeyFrames>
							</Storyboard>
							<Storyboard x:Key="OverlayClosingAnimation">
								<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity">
									<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="1.0"/>
									<SplineDoubleKeyFrame KeySpline="0.1,0.9 0.2,1.0" KeyTime="0:0:0.216" Value="0.0"/>
								</DoubleAnimationUsingKeyFrames>
							</Storyboard>
						</Grid.Resources>
						<Grid.ColumnDefinitions>
							<ColumnDefinition Width="*"/>
							<ColumnDefinition Width="32"/>
						</Grid.ColumnDefinitions>
						<Grid.RowDefinitions>
							<RowDefinition Height="Auto"/>
							<RowDefinition Height="*"/>
						</Grid.RowDefinitions>
						<VisualStateManager.VisualStateGroups>
							<VisualStateGroup x:Name="CommonStates">
								<VisualState x:Name="Normal"/>
								<VisualState x:Name="PointerOver">
									<Storyboard>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Background">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ComboBoxBackgroundPointerOver}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="Background">
											<DiscreteObjectKeyFrame KeyTime="0" Value="GoldenRod"/>
										</ObjectAnimationUsingKeyFrames>
									</Storyboard>
								</VisualState>
								<VisualState x:Name="Pressed">
									<Storyboard>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Background">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ComboBoxBackgroundPressed}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="Background">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ComboBoxBorderBrushPressed}"/>
										</ObjectAnimationUsingKeyFrames>
									</Storyboard>
								</VisualState>
								<VisualState x:Name="Disabled">
									<Storyboard>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Background">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ComboBoxBackgroundDisabled}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="Background">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ComboBoxBorderBrushDisabled}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="HeaderContentPresenter">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ComboBoxForegroundDisabled}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ComboBoxForegroundDisabled}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="PlaceholderTextBlock">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ComboBoxForegroundDisabled}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="DropDownGlyph">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ComboBoxDropDownGlyphForegroundDisabled}"/>
										</ObjectAnimationUsingKeyFrames>
									</Storyboard>
								</VisualState>
							</VisualStateGroup>
							<VisualStateGroup x:Name="FocusStates">
								<VisualState x:Name="Focused">
									<Storyboard>
										<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="HighlightBackground"/>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="HighlightBackground">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ComboBoxBackgroundBorderBrushFocused}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ComboBoxForegroundFocused}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="PlaceholderTextBlock">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ComboBoxForegroundFocused}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="DropDownGlyph">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ComboBoxDropDownGlyphForegroundFocused}"/>
										</ObjectAnimationUsingKeyFrames>
									</Storyboard>
								</VisualState>
								<VisualState x:Name="FocusedPressed">
									<Storyboard>
										<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="HighlightBackground"/>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ComboBoxForegroundFocusedPressed}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="PlaceholderTextBlock">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ComboBoxPlaceHolderForegroundFocusedPressed}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="DropDownGlyph">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ComboBoxDropDownGlyphForegroundFocusedPressed}"/>
										</ObjectAnimationUsingKeyFrames>
									</Storyboard>
								</VisualState>
								<VisualState x:Name="Unfocused"/>
								<VisualState x:Name="PointerFocused"/>
								<VisualState x:Name="FocusedDropDown">
									<Storyboard>
										<ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="PopupBorder">
											<DiscreteObjectKeyFrame KeyTime="0">
												<DiscreteObjectKeyFrame.Value>
													<Visibility>Visible</Visibility>
												</DiscreteObjectKeyFrame.Value>
											</DiscreteObjectKeyFrame>
										</ObjectAnimationUsingKeyFrames>
									</Storyboard>
								</VisualState>
							</VisualStateGroup>
							<VisualStateGroup x:Name="DropDownStates">
								<VisualState x:Name="Opened">
									<Storyboard>
										<SplitOpenThemeAnimation ClosedTargetName="ContentPresenter" 
										OffsetFromCenter="{Binding TemplateSettings.DropDownOffset, RelativeSource={RelativeSource Mode=TemplatedParent}}" 
										OpenedTargetName="PopupBorder" OpenedLength="{Binding TemplateSettings.DropDownOpenedHeight, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
									</Storyboard>
								</VisualState>
								<VisualState x:Name="Closed">
									<Storyboard>
										<SplitCloseThemeAnimation ClosedTargetName="ContentPresenter" 
										OffsetFromCenter="{Binding TemplateSettings.DropDownOffset, RelativeSource={RelativeSource Mode=TemplatedParent}}" 
										OpenedTargetName="PopupBorder" OpenedLength="{Binding TemplateSettings.DropDownOpenedHeight, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
									</Storyboard>
								</VisualState>
							</VisualStateGroup>
						</VisualStateManager.VisualStateGroups>
						<Border x:Name="Background" BorderBrush="Salmon" BorderThickness="{TemplateBinding BorderThickness}" 
						Background="LightSalmon" Grid.ColumnSpan="2" Grid.Row="1" CornerRadius="15"/>
						<Border x:Name="HighlightBackground" BorderBrush="Gold" BorderThickness="{TemplateBinding BorderThickness}" 
						Background="{ThemeResource ComboBoxBackgroundUnfocused}" Grid.ColumnSpan="2" Opacity="0" Grid.Row="1" CornerRadius="15"/>
						<ContentPresenter x:Name="ContentPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
						Margin="{TemplateBinding Padding}" Grid.Row="1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" CornerRadius="15">
							<TextBlock x:Name="PlaceholderTextBlock" Foreground="{ThemeResource ComboBoxPlaceHolderForeground}" 
							Text="{TemplateBinding PlaceholderText}"/>
						</ContentPresenter>
						<FontIcon x:Name="DropDownGlyph" AutomationProperties.AccessibilityView="Raw" Grid.Column="1" Foreground="Gold" 
						FontSize="12" FontFamily="{ThemeResource SymbolThemeFontFamily}" Glyph="" HorizontalAlignment="Right" 
						IsHitTestVisible="False" Margin="0,10,10,10" Grid.Row="1" VerticalAlignment="Center"/>
						<Popup x:Name="Popup">
							<Border x:Name="PopupBorder" BorderBrush="Salmon" 
							BorderThickness="{ThemeResource ComboBoxDropdownBorderThickness}" 
							Background="LightSalmon" HorizontalAlignment="Stretch" 
							Margin="0,-1,0,-1" CornerRadius="15">
								<ScrollViewer x:Name="ScrollViewer" AutomationProperties.AccessibilityView="Raw" 
								BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}" 
								Foreground="{ThemeResource ComboBoxDropDownForeground}" 
								HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" 
								HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" 
								IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" 
								IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" 
								IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" 
								MinWidth="{Binding TemplateSettings.DropDownContentMinWidth, RelativeSource={RelativeSource Mode=TemplatedParent}}" 
								VerticalSnapPointsType="OptionalSingle" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" 
								VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" VerticalSnapPointsAlignment="Near" ZoomMode="Disabled">
									<ItemsPresenter Margin="{ThemeResource ComboBoxDropdownContentMargin}"/>
								</ScrollViewer>
							</Border>
						</Popup>
					</Grid>
				</ControlTemplate>
			</Setter.Value>
		</Setter>
	</Style>
</Application.Resources>

Step 8

From the Solution Explorer select MainPage.xaml

vs2017-mainpage

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<ComboBox SelectedIndex="0" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource CustomComboBox}">
	<ComboBoxItem Content="ComboBox"/>
	<ComboBoxItem Content="One"/>
	<ComboBoxItem Content="Two"/>
	<ComboBoxItem Content="Three"/>
	<ComboBoxItem Content="Four"/>
</ComboBox>

It should appear as such:

xaml-custom-combobox

Step 11

That completes the Universal Windows Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-debug

Step 12

Once started the Application should then appear

run-custom-combobox

Step 13

After the Application has started running you can then select ComboBox if not already and then select one of the items from the ComboBox

ran-custom-combobox

Step 14

To Exit the application select Stop in Visual Studio

vs2017-stop

Creative Commons License

Universal Windows Platform – Custom TextBox

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu locate and select Visual Studio 2017.

vs2017-home

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project

vs2017-new-project

Step 4

Then in New Universal Windows Project you need to select the Target Version to be Windows 10 Creators Update (10.0; Build 15063) and the Minimum Version to be at least Windows 10 Anniversary Update (10.0; Build 14393) or Windows 10 Creators Update (10.0; Build 15063)

vs2017-platform

Step 5

In the Solution Explorer select App.xaml

vs2017-app

Step 6

From the Menu choose View and then Designer

vs2017-view-designer

Step 7

The XAML View and in this between the Application and /Application elements, enter the following XAML:

<Application.Resources>
	<Style x:Key="CustomTextBox" TargetType="TextBox">
		<Setter Property="MinWidth" Value="{ThemeResource TextControlThemeMinWidth}"/>
		<Setter Property="MinHeight" Value="{ThemeResource TextControlThemeMinHeight}"/>
		<Setter Property="Foreground" Value="Gold"/>
		<Setter Property="Background" Value="{ThemeResource TextControlBackground}"/>
		<Setter Property="SelectionHighlightColor" Value="{ThemeResource TextControlSelectionHighlightColor}"/>
		<Setter Property="BorderThickness" Value="2"/>
		<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
		<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
		<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Auto"/>
		<Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto"/>
		<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden"/>
		<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden"/>
		<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False"/>
		<Setter Property="Padding" Value="{ThemeResource TextControlThemePadding}"/>
		<Setter Property="Template">
			<Setter.Value>
				<ControlTemplate TargetType="TextBox">
					<Grid>
						<Grid.ColumnDefinitions>
							<ColumnDefinition Width="*"/>
							<ColumnDefinition Width="Auto"/>
						</Grid.ColumnDefinitions>
						<Grid.RowDefinitions>
							<RowDefinition Height="Auto"/>
							<RowDefinition Height="*"/>
						</Grid.RowDefinitions>
						<VisualStateManager.VisualStateGroups>
							<VisualStateGroup x:Name="CommonStates">
								<VisualState x:Name="Disabled">
									<Storyboard>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="HeaderContentPresenter">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlHeaderForegroundDisabled}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BorderElement">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundDisabled}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushDisabled}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundDisabled}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="PlaceholderTextContentPresenter">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlPlaceholderForegroundDisabled}"/>
										</ObjectAnimationUsingKeyFrames>
									</Storyboard>
								</VisualState>
								<VisualState x:Name="Normal"/>
								<VisualState x:Name="PointerOver">
									<Storyboard>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement">
											<DiscreteObjectKeyFrame KeyTime="0" Value="GoldenRod"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BorderElement">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundPointerOver}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="PlaceholderTextContentPresenter">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlPlaceholderForegroundPointerOver}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundPointerOver}"/>
										</ObjectAnimationUsingKeyFrames>
									</Storyboard>
								</VisualState>
								<VisualState x:Name="Focused">
									<Storyboard>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="PlaceholderTextContentPresenter">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlPlaceholderForegroundFocused}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BorderElement">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundFocused}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement">
											<DiscreteObjectKeyFrame KeyTime="0" Value="Gold"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">
											<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundFocused}"/>
										</ObjectAnimationUsingKeyFrames>
										<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="RequestedTheme" Storyboard.TargetName="ContentElement">
											<DiscreteObjectKeyFrame KeyTime="0" Value="Light"/>
										</ObjectAnimationUsingKeyFrames>
									</Storyboard>
								</VisualState>
							</VisualStateGroup>
						</VisualStateManager.VisualStateGroups>
						<Border x:Name="BorderElement" BorderBrush="Salmon" BorderThickness="{TemplateBinding BorderThickness}" Background="LightSalmon" Grid.ColumnSpan="2" Grid.Row="1" Grid.RowSpan="1" CornerRadius="15"/>
						<ScrollViewer x:Name="ContentElement" AutomationProperties.AccessibilityView="Raw" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" 
						HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsTabStop="False" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" 
						IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" Margin="{TemplateBinding BorderThickness}" 
						Padding="{TemplateBinding Padding}" Grid.Row="1" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" 
						ZoomMode="Disabled"/>
						<ContentPresenter x:Name="PlaceholderTextContentPresenter" Grid.ColumnSpan="2" Content="{TemplateBinding PlaceholderText}" Foreground="Gold" IsHitTestVisible="False" Margin="{TemplateBinding BorderThickness}" 
						Padding="{TemplateBinding Padding}" Grid.Row="1" TextWrapping="{TemplateBinding TextWrapping}"/>
					</Grid>
				</ControlTemplate>
			</Setter.Value>
		</Setter>
	</Style>
</Application.Resources>

Step 8

From the Solution Explorer select MainPage.xaml

vs2017-mainpage

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<TextBox Text="TextBox" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource CustomTextBox}"/>

It should appear as such:

xaml-custom-textbox

Step 11

That completes the Universal Windows Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-debug

Step 12

Once started the Application should then appear

run-custom-textbox

Step 13

After the Application has started running you can then select TextBox if not already and then type in some Text then you can deselect the TextBox once finished

ran-custom-textbox

Step 14

To Exit the application select Stop in Visual Studio

vs2017-stop

Creative Commons License

Universal Windows Platform – Contacts App

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu locate and select Visual Studio 2017.

vs2017-home

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project

vs2017-new-project

Step 4

Then in New Universal Windows Project you need to select the Target Version to be Windows 10 Creators Update (10.0; Build 15063) and the Minimum Version to be at least Windows 10 Anniversary Update (10.0; Build 14393) or Windows 10 Creators Update (10.0; Build 15063)

vs2017-platform

Step 5

From the Menu choose Project, then Add New Item…

vs2017-add-new-item

Step 6

From the Add New Item choose Visual C# from Installed then choose Code then select Code File and then in the Name as Library.cs and then select Add to add the file to the Project

vs2017-library

Step 7

Then in the Code View for Library.cs the following should be entered:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel.Contacts;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;

public class Item
{
    public string Id { get; set; }
    public string Address { get; set; }
    public string DisplayName { get; set; }
}

public class Library
{
    private const string contacts_list = "Contacts App";

    private async Task<ContactStore> Store()
    {
        return await ContactManager.RequestStoreAsync(ContactStoreAccessType.AppContactsReadWrite);
    }

    private InputScope Scope(InputScopeNameValue value)
    {
        InputScope scope = new InputScope();
        InputScopeName name = new InputScopeName()
        {
            NameValue = value
        };
        scope.Names.Add(name);
        return scope;
    }

    private async Task<Contact> Dialog(Contact contact)
    {
        Thickness margin = new Thickness(5);
        TextBox firstname = new TextBox()
        {
            Text = contact.FirstName,
            Margin = margin,
            PlaceholderText = "First Name"
        };
        TextBox lastname = new TextBox()
        {
            Text = contact.LastName,
            Margin = margin,
            PlaceholderText = "Last Name"
        };
        TextBox email = new TextBox()
        {
            Text = contact?.Emails?.FirstOrDefault()?.Address ?? string.Empty,
            Margin = margin,
            PlaceholderText = "Email Address",
            InputScope = Scope(InputScopeNameValue.EmailSmtpAddress)         
        };
        StackPanel panel = new StackPanel()
        {
            Orientation = Orientation.Vertical
        };
        panel.Children.Add(firstname);
        panel.Children.Add(lastname);
        panel.Children.Add(email);
        ContentDialog dialog = new ContentDialog()
        {
            Title = "Contact",
            PrimaryButtonText = "Save",
            CloseButtonText = "Cancel",
            Content = panel
        };
        ContentDialogResult result = await dialog.ShowAsync();
        if (result == ContentDialogResult.Primary)
        {
            contact.FirstName = firstname.Text;
            contact.LastName = lastname.Text;
            contact.Emails.Add(new ContactEmail() { Address = email.Text });
            return contact;
        }
        return null;
    }

    private async Task<ContactList> GetAsync()
    {
        ContactList result = null;
        ContactStore store = await Store();
        if (store != null)
        {
            IReadOnlyList<ContactList> list = await store.FindContactListsAsync();
            if(list.Count == 0)
            {
                result = await store.CreateContactListAsync(contacts_list);
            }
            else
            {
                result = list.FirstOrDefault(s => s.DisplayName == contacts_list);
            }
        }
        return result;
    }

    private async Task<IReadOnlyList<Contact>> ListContactsAsync()
    {
        ContactStore store = await Store();
        if (store != null)
        {
            ContactList list = await GetAsync();
            if (list != null)
            {
                ContactReader reader = list.GetContactReader();
                if (reader != null)
                {
                    ContactBatch batch = await reader.ReadBatchAsync();
                    if (batch != null)
                    {
                        return batch.Contacts;
                    }
                }
            }
        }
        return null;
    }

    private async Task<Contact> GetContactAsync(string id)
    {
        ContactList list = await GetAsync();
        if (list != null)
        {
            return await list.GetContactAsync(id);
        }
        return null;
    }

    public async Task<List<Item>> ListAsync()
    {
        List<Item> results = new List<Item>();
        IReadOnlyList<Contact> contacts = await ListContactsAsync();
        foreach (Contact contact in contacts)
        {
            results.Add(new Item
            {
                Id = contact.Id,
                DisplayName = contact.DisplayName,
                Address = contact?.Emails?.FirstOrDefault()?.Address
            });
        }
        return results;
    }

    public async Task<bool> Add(AppBarButton button)
    {
        Contact contact = await Dialog(new Contact());
        if(contact != null)
        {
            ContactList list = await GetAsync();
            if(list != null)
            {
               await list.SaveContactAsync(contact);
               return true;
            }
        }
        return false;
    }

    public async Task<bool> Edit(AppBarButton button)
    {
        Item item = (Item)button.Tag;
        Contact contact = await GetContactAsync(item.Id);
        if (contact != null)
        {
            contact = await Dialog(contact);
            if (contact != null)
            {
                ContactList list = await GetAsync();
                if (list != null)
                {
                    await list.SaveContactAsync(contact);
                    return true;
                }
            }
        }
        return false;
    }

    public async Task<bool> Delete(AppBarButton button)
    {
        Item item = (Item)button.Tag;
        Contact contact = await GetContactAsync(item.Id);
        if(contact != null)
        {
            ContactList list = await GetAsync();
            if (list != null)
            {
                await list.DeleteContactAsync(contact);
                return true;
            }
        }
        return false;
    }
}

Step 8

Then in the Solution Explorer select MainPage.xaml

vs2017-library-mainpage

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Grid>
	<Grid.RowDefinitions>
		<RowDefinition Height="*"/>
		<RowDefinition Height="Auto"/>
	</Grid.RowDefinitions>
	<CommandBar Grid.Row="1">
		<AppBarButton Name="Add" Icon="Add" Label="New" Click="Add_Click"/>
	</CommandBar>
	<ListBox Grid.Row="0" Name="Display" Loaded="Display_Loaded">
		<ListBox.ItemContainerStyle>
			<Style TargetType="ListBoxItem">
				<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
			</Style>
		</ListBox.ItemContainerStyle>
		<ListBox.ItemTemplate>
			<DataTemplate>
				<Grid>
					<Grid.ColumnDefinitions>
						<ColumnDefinition Width="40*"/>
						<ColumnDefinition Width="40*"/>
						<ColumnDefinition Width="Auto"/>
					</Grid.ColumnDefinitions>
					<Grid Padding="5" Grid.Column="0" Background="{ThemeResource AccentButtonBackground}">
						<TextBlock Text="{Binding DisplayName}" VerticalAlignment="Center"
							Foreground="{ThemeResource AccentButtonForeground}"/>
					</Grid>
					<Grid Padding="5" Grid.Column="1" Background="{ThemeResource AccentButtonForeground}">
						<TextBlock Text="{Binding Address}" VerticalAlignment="Center"
							Foreground="{ThemeResource AccentButtonBackground}"/>
					</Grid>
					<StackPanel Grid.Column="3" Orientation="Horizontal">
						<AppBarButton Name="Edit" Icon="Edit" Label="Edit" Tag="{Binding}" Click="Edit_Click"/>
						<AppBarButton Name="Delete" Icon="Delete" Label="Delete" Tag="{Binding}" Click="Delete_Click"/>
					</StackPanel>
				</Grid>
			</DataTemplate>
		</ListBox.ItemTemplate>
	</ListBox>
</Grid>

It should appear as such:

xaml-contacts-app

Step 11

From the Menu choose View and then Code

vs2017-view-code

Step 12

Once in the Code View, below the public MainPage() { … } the following Code should be entered:

Library library = new Library();

private async void Display_Loaded(object sender, RoutedEventArgs e)
{
	Display.ItemsSource = await library.ListAsync();
}

private async void Add_Click(object sender, RoutedEventArgs e)
{
	if (await library.Add(Add))
	{
		Display.ItemsSource = await library.ListAsync();
	}
}

private async void Edit_Click(object sender, RoutedEventArgs e)
{
	if (await library.Edit((AppBarButton)sender))
	{ 
		Display.ItemsSource = await library.ListAsync();
	}
}

private async void Delete_Click(object sender, RoutedEventArgs e)
{
	if (await library.Delete((AppBarButton)sender))
	{
		Display.ItemsSource = await library.ListAsync();
	}
}

It should then appear as such:

code-contacts-app

Step 13

Then in the Solution Explorer select Package.appxmanifest

vs2017-library-manifest

Step 14

Then from the Menu choose View and then Designer

vs2017-view-designer

Step 15

The Design View will be displayed for the Package.appxmanifest, then select the Capabilities Tab and Tick the Contacts option from the list of Capabilities

manifest-contact-app

Step 16

That completes the Universal Windows Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-debug

Step 17

Once started the Application should then appear

run-contacts-app

Step 18

After the Application has started running you can then select Add to create a new Contact, this will display a Dialog where you can enter the First Name, Last Name and Email Address for a Contact. Contacts added will be displayed in the List where you can Edit or Delete them.

ran-contacts-app

Step 19

To Exit the application select Stop in Visual Studio

vs2017-stop

Creative Commons License

Universal Windows Platform – Calendar App

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu locate and select Visual Studio 2017.

vs2017-home

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project

vs2017-new-project

Step 4

Then in New Universal Windows Project you need to select the Target Version to be Windows 10 Creators Update (10.0; Build 15063) and the Minimum Version to be at least Windows 10 Anniversary Update (10.0; Build 14393) or Windows 10 Creators Update (10.0; Build 15063)

vs2017-platform

Step 5

From the Menu choose Project, then Add New Item…

vs2017-add-new-item

Step 6

From the Add New Item choose Visual C# from Installed then choose Code then select Code File and then in the Name as Library.cs and then select Add to add the file to the Project

vs2017-library

Step 7

Then in the Code View for Library.cs the following should be entered:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel.Appointments;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

public class Item
{
    public string Id { get; set; }
    public DateTimeOffset StartTime { get; set; }
    public string When { get { return StartTime.ToString("dd MMMM yyyy HH:mm:ss"); } }
    public string Subject { get; set; }
    public string Details { get; set; }
}

public class Library
{
    private const string appointment_calendar = "Calendar App";

    private async Task<AppointmentStore> Store()
    {
        return await AppointmentManager.RequestStoreAsync(AppointmentStoreAccessType.AppCalendarsReadWrite);
    }

    private DateTime GetDateTime(DateTimeOffset date, TimeSpan time)
    {
        return new DateTime(date.Year, date.Month, date.Day, time.Hours, time.Minutes, time.Seconds);
    }

    private async Task<Appointment> Dialog(Appointment appointment, ResourceDictionary resources)
    {
        Thickness margin = new Thickness(5);
        DatePicker date = new DatePicker()
        {
            Date = appointment.StartTime,
            Margin = margin,
            HorizontalAlignment = HorizontalAlignment.Stretch
        };
        TimePicker time = new TimePicker()
        {
            Time = appointment.StartTime.TimeOfDay,
            Margin = margin,
            HorizontalAlignment = HorizontalAlignment.Stretch
        };
        TextBox subject = new TextBox()
        {
            Text = appointment.Subject,
            Margin = margin,
            PlaceholderText = "Subject"
        };
        TextBox details = new TextBox()
        {
            Text = appointment.Details,
            Margin = margin,
            PlaceholderText = "Details",
            AcceptsReturn = true,
            TextWrapping = TextWrapping.Wrap,
            Height = (double)resources["SearchBoxSuggestionPopupThemeMaxHeight"]
        };
        StackPanel panel = new StackPanel()
        {
            Orientation = Orientation.Vertical
        };
        panel.Children.Add(date);
        panel.Children.Add(time);
        panel.Children.Add(subject);
        panel.Children.Add(details);
        ContentDialog dialog = new ContentDialog()
        {
            Title = "Appointment",
            PrimaryButtonText = "Save",
            CloseButtonText = "Cancel",
            Content = panel
        };
        ContentDialogResult result = await dialog.ShowAsync();
        if (result == ContentDialogResult.Primary)
        {
            appointment.StartTime = GetDateTime(date.Date, time.Time);
            appointment.Subject = subject.Text;
            appointment.Details = details.Text;
            return appointment;
        }
        return null;
    }

    private async Task<AppointmentCalendar> GetAsync()
    {
        AppointmentCalendar result = null;
        AppointmentStore store = await Store();
        if (store != null)
        {
            IReadOnlyList<AppointmentCalendar> list = await store.FindAppointmentCalendarsAsync();
            if (list.Count == 0)
            {
                result = await store.CreateAppointmentCalendarAsync(appointment_calendar);
            }
            else
            {
                result = list.FirstOrDefault(s => s.DisplayName == appointment_calendar);
            }
        }
        return result;
    }

    private async Task<IReadOnlyList<Appointment>> ListAppointmentsAsync(DateTimeOffset start, TimeSpan range)
    {
        AppointmentStore store = await Store();
        if (store != null)
        {
            AppointmentCalendar calendar = await GetAsync();
            if (calendar != null)
            {
                return await calendar.FindAppointmentsAsync(start, range);
            }
        }
        return null;
    }

    private async Task<Appointment> GetAppointmentAsync(string id)
    {
        AppointmentCalendar calendar = await GetAsync();
        if (calendar != null)
        {
            return await calendar.GetAppointmentAsync(id);
        }
        return null;
    }

    public void Start(ref CalendarDatePicker picker)
    {
        DateTime now = DateTime.Now;
        if (picker.Date == null)
        {
            picker.Date = GetDateTime(DateTime.Now, new TimeSpan(0, 0, 0));
        }
    }

    public async Task<List<Item>> ListAsync(DateTimeOffset start)
    {
        DateTimeOffset finish = start.AddMonths(1);
        TimeSpan range = finish - start;
        List<Item> results = new List<Item>();
        IReadOnlyList<Appointment> appointments = await ListAppointmentsAsync(start, range);
        foreach (Appointment appointment in appointments)
        {
            results.Add(new Item()
            {
                Id = appointment.LocalId,
                StartTime = appointment.StartTime,
                Subject = appointment.Subject,
                Details = appointment.Details
            });
        }
        return results;
    }

    public async Task<bool> Add(AppBarButton button, ResourceDictionary resources)
    {
        Appointment appointment = await Dialog(new Appointment(), resources);
        if (appointment != null)
        {
            AppointmentCalendar calendar = await GetAsync();
            if (calendar != null)
            {
                await calendar.SaveAppointmentAsync(appointment);
                return true;
            }
        }
        return false;
    }

    public async Task<bool> Edit(AppBarButton button, ResourceDictionary resources)
    {
        Item item = (Item)button.Tag;
        Appointment appointment = await GetAppointmentAsync(item.Id);
        if (appointment != null)
        {
            appointment = await Dialog(appointment, resources);
            if (appointment != null)
            {
                AppointmentCalendar calendar = await GetAsync();
                if (calendar != null)
                {
                    await calendar.SaveAppointmentAsync(appointment);
                    return true;
                }
            }
        }
        return false;
    }

    public async Task<bool> Delete(AppBarButton button)
    {
        Item item = (Item)button.Tag;
        Appointment appointment = await GetAppointmentAsync(item.Id);
        if (appointment != null)
        {
            AppointmentCalendar calendar = await GetAsync();
            if (calendar != null)
            {
                await calendar.DeleteAppointmentAsync(item.Id);
                return true;
            }
        }
        return false;
    }
}

Step 8

Then in the Solution Explorer select MainPage.xaml

vs2017-library-mainpage

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Grid>
	<Grid.RowDefinitions>
		<RowDefinition Height="Auto"/>
		<RowDefinition Height="*"/>
		<RowDefinition Height="Auto"/>
	</Grid.RowDefinitions>
	<CommandBar Grid.Row="2">
		<AppBarButton Name="Add" Icon="Add" Label="New" Click="Add_Click"/>
	</CommandBar>
	<CalendarDatePicker Grid.Row="0" Name="Picker" HorizontalAlignment="Stretch"
		 PlaceholderText="Display Appointments From" DateChanged="Picker_DateChanged"/>
	<ListBox Grid.Row="1" Name="Display" Loaded="Display_Loaded">
		<ListBox.ItemContainerStyle>
			<Style TargetType="ListBoxItem">
				<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
			</Style>
		</ListBox.ItemContainerStyle>
		<ListBox.ItemTemplate>
			<DataTemplate>
				<Grid>
					<Grid.ColumnDefinitions>
						<ColumnDefinition Width="40*"/>
						<ColumnDefinition Width="40*"/>
						<ColumnDefinition Width="Auto"/>
					</Grid.ColumnDefinitions>
					<Grid Padding="5" Grid.Column="0" Background="{ThemeResource AccentButtonBackground}">
						<TextBlock Text="{Binding When}" VerticalAlignment="Center"
							Foreground="{ThemeResource AccentButtonForeground}"/>
					</Grid>
					<Grid Padding="5" Grid.Column="1" Background="{ThemeResource AccentButtonForeground}">
						<TextBlock Text="{Binding Subject}" VerticalAlignment="Center"
							Foreground="{ThemeResource AccentButtonBackground}"/>
					</Grid>
					<StackPanel Grid.Column="3" Orientation="Horizontal">
						<AppBarButton Name="Edit" Icon="Edit" Label="Edit" Tag="{Binding}" Click="Edit_Click"/>
						<AppBarButton Name="Delete" Icon="Delete" Label="Delete" Tag="{Binding}" Click="Delete_Click"/>
					</StackPanel>
				</Grid>
			</DataTemplate>
		</ListBox.ItemTemplate>
	</ListBox>
</Grid>

It should appear as such:

xaml-calendar-app

Step 11

From the Menu choose View and then Code

vs2017-view-code

Step 12

Once in the Code View, below the public MainPage() { … } the following Code should be entered:

Library library = new Library();

private async void Picker_DateChanged(CalendarDatePicker sender, CalendarDatePickerDateChangedEventArgs args)
{
	Display.ItemsSource = await library.ListAsync((DateTimeOffset)Picker.Date);
}

private async void Display_Loaded(object sender, RoutedEventArgs e)
{
	library.Start(ref Picker);
	Display.ItemsSource = await library.ListAsync((DateTimeOffset)Picker.Date);
}

private async void Add_Click(object sender, RoutedEventArgs e)
{
	if(await library.Add(Add, App.Current.Resources))
	{
		Display.ItemsSource = await library.ListAsync((DateTimeOffset)Picker.Date);
	}
}

private async void Edit_Click(object sender, RoutedEventArgs e)
{
	if (await library.Edit((AppBarButton)sender, App.Current.Resources))
	{
		Display.ItemsSource = await library.ListAsync((DateTimeOffset)Picker.Date);
	}
}

private async void Delete_Click(object sender, RoutedEventArgs e)
{
	if (await library.Delete((AppBarButton)sender))
	{
		Display.ItemsSource = await library.ListAsync((DateTimeOffset)Picker.Date);
	}
}

It should then appear as such:

code-calendar-app

Step 13

Then in the Solution Explorer select Package.appxmanifest

vs2017-library-manifest

Step 14

Then from the Menu choose View and then Designer

vs2017-view-designer

Step 15

The Design View will be displayed for the Package.appxmanifest, then select the Capabilities Tab and Tick the Appointments option from the list of Capabilities

manifest-calendar-app

Step 16

That completes the Universal Windows Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-debug

Step 17

Once started the Application should then appear

run-calendar-app

Step 18

After the Application has started running you can then select Add to create a new Appointment, this will display a Dialog where you can enter the Date, Time, Subject and Details for an Appointment. Appointments added will be displayed in the List where you can Edit or Delete them and you can control the date range to start showing Appointments from with the CalendarDatePicker at the top.

ran-calendar-app

Step 19

To Exit the application select Stop in Visual Studio

vs2017-stop

Creative Commons License

Universal Windows Platform – Speaking App

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu locate and select Visual Studio 2017.

vs2017-home

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project

vs2017-new-project

Step 4

Then in New Universal Windows Project you need to select the Target Version to be Windows 10 Creators Update (10.0; Build 15063) and the Minimum Version to be at least Windows 10 Anniversary Update (10.0; Build 14393) or Windows 10 Creators Update (10.0; Build 15063)

vs2017-platform

Step 5

From the Menu choose Project, then Add New Item…

vs2017-add-new-item

Step 6

From the Add New Item choose Visual C# from Installed then choose Code then select Code File and then in the Name as Library.cs and then select Add to add the file to the Project

vs2017-library

Step 7

Then in the Code View for Library.cs the following should be entered:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Media.SpeechSynthesis;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

public class Library
{
    private const string extension_txt = ".txt";
    private const string extension_wav = ".wav";

    private SpeechSynthesizer synth = new SpeechSynthesizer();

    private async Task<string> OpenAsync()
    {
        try
        {
            FileOpenPicker picker = new FileOpenPicker()
            {
                SuggestedStartLocation = PickerLocationId.ComputerFolder
            };
            picker.FileTypeFilter.Add(extension_txt);
            StorageFile open = await picker.PickSingleFileAsync();
            if (open != null)
            {
                return await FileIO.ReadTextAsync(open);
            }
        }
        finally
        {
        }
        return null;
    }

    private async void SaveAsync(string contents)
    {
        try
        {
            FileSavePicker picker = new FileSavePicker()
            {
                SuggestedStartLocation = PickerLocationId.DocumentsLibrary,
                DefaultFileExtension = extension_txt,
                SuggestedFileName = "Document"
            };
            picker.FileTypeChoices.Add("Text File", new List<string>() { extension_txt });
            picker.FileTypeChoices.Add("Wave File", new List<string>() { extension_wav });
            StorageFile save = await picker.PickSaveFileAsync();
            if (save != null)
            {
                if (save.FileType == extension_txt)
                {
                    await FileIO.WriteTextAsync(save, contents);
                }
                else if (save.FileType == extension_wav)
                {
                    using (SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync(contents))
                    {
                        using (DataReader reader = new DataReader(stream))
                        {
                            await reader.LoadAsync((uint)stream.Size);
                            IBuffer buffer = reader.ReadBuffer((uint)stream.Size);
                            await FileIO.WriteBufferAsync(save, buffer);
                        }
                    }
                }
            }
        }
        finally
        {
        }
    }

    private async void Speak(string text, MediaElement media)
    {
        try
        {
            if (media.CurrentState == MediaElementState.Playing)
            {
                media.Stop();
            }
            else
            {
                SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync(text);
                media.AutoPlay = true;
                media.SetSource(stream, stream.ContentType);
                media.Play();
            }
        }
        finally
        {
        }
    }

    public Dictionary<string, string> Voices()
    {
        Dictionary<string, string> results = new Dictionary<string, string>();
        foreach (VoiceInformation voice in SpeechSynthesizer.AllVoices.OrderBy(o => o.DisplayName))
        {
            results.Add(voice.Id, voice.DisplayName);
        }
        return results;
    }

    public void Voice(string id)
    {
        synth.Voice = SpeechSynthesizer.AllVoices.First(f => f.Id == id);
    }

    public void New(ref TextBox text, ref MediaElement media)
    {
        media.Source = null;
        text.Text = string.Empty;
    }

    public async void Open(TextBox text)
    {
        string content = await OpenAsync();
        if (content != null)
        {
            text.Text = content;
        }
    }

    public void Save(ref TextBox text)
    {
        SaveAsync(text.Text);
    }

    public void Play(ref TextBox text, ref MediaElement media)
    {
        Speak(text.Text, media);
    }
}

Step 8

Then in the Solution Explorer select MainPage.xaml

vs2017-library-mainpage

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Grid Name="Display" Loaded="Display_Loaded">
	<Grid.RowDefinitions>
		<RowDefinition Height="Auto"/>
		<RowDefinition Height="*"/>
		<RowDefinition Height="Auto"/>
	</Grid.RowDefinitions>
	<CommandBar Grid.Row="2">
		<AppBarButton Name="New" Icon="Page2" Label="New" Click="New_Click"/>
		<AppBarButton Name="Open" Icon="OpenFile" Label="Open" Click="Open_Click"/>
		<AppBarButton Name="Save" Icon="Save" Label="Save" Click="Save_Click"/>
		<AppBarButton Name="Play" Icon="Play" Label="Play" Click="Play_Click"/>
	</CommandBar>
	<ComboBox Grid.Row="0" Name="Voice" HorizontalAlignment="Stretch" 
		SelectedValuePath="Key" DisplayMemberPath="Value" 
		SelectionChanged="Voice_SelectionChanged"/>
	<TextBox Grid.Row="1" Name="Input" AcceptsReturn="True" TextWrapping="Wrap"/>
	<MediaElement Name="Media" AutoPlay="False"/>
</Grid>

It should appear as such:

xaml-speaking-app

Step 11

From the Menu choose View and then Code

vs2017-view-code

Step 12

Once in the Code View, below the public MainPage() { … } the following Code should be entered:

Library library = new Library();

private void Display_Loaded(object sender, RoutedEventArgs e)
{
	Voice.ItemsSource = library.Voices();
	Voice.SelectedIndex = 0;
}

private void Voice_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
	library.Voice((string)Voice.SelectedValue);
}

private void New_Click(object sender, RoutedEventArgs e)
{
	library.New(ref Input, ref Media);
}

private void Open_Click(object sender, RoutedEventArgs e)
{
	library.Open(Input);
}

private void Save_Click(object sender, RoutedEventArgs e)
{
	library.Save(ref Input);
}

private void Play_Click(object sender, RoutedEventArgs e)
{
	library.Play(ref Input, ref Media);
}

It should then appear as such:

code-speaking-app

Step 13

That completes the Universal Windows Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-debug

Step 14

Once started the Application should then appear

run-speaking-app

Step 15

After the Application has started running you can then select New to reset the TextBox or use Open to set the content to a Text Document or Save contents to a Text Document or Speech to a Wave File and use Play to convert content from text-to-speech – you can choose the Voice to speak with from the ComboBox at the top.

ran-speaking-app

Step 16

To Exit the application select Stop in Visual Studio

vs2017-stop

Creative Commons License

Universal Windows Platform – Operator App

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu locate and select Visual Studio 2017.

vs2017-home

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project

vs2017-new-project

Step 4

Then in New Universal Windows Project you need to select the Target Version to be Windows 10 Creators Update (10.0; Build 15063) and the Minimum Version to be at least Windows 10 Anniversary Update (10.0; Build 14393) or Windows 10 Creators Update (10.0; Build 15063)

vs2017-platform

Step 5

From the Menu choose Project, then Add New Item…

vs2017-add-new-item

Step 6

From the Add New Item choose Visual C# from Installed then choose Code then select Code File and then in the Name as Library.cs and then select Add to add the file to the Project

vs2017-library

Step 7

Then in the Code View for Library.cs the following should be entered:

using System;
using System.Collections.Generic;
using System.Windows.Input;
using Windows.UI.Xaml.Controls;

public class CommandHandler : ICommand
{
    public event EventHandler CanExecuteChanged = null;
    private Action _action;

    public CommandHandler(Action action)
    {
        _action = action;
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        _action();
    }
}

public class Item
{
    public enum ItemMode
    {
        Operand = 1,
        Operator = 2
    }

    public ItemMode Mode { get; set; }
    public Func<Item, int> Action { get; set; }
    public ICommand Command { get { return new CommandHandler(() => this.Action(this)); } }
    public object Value { get; set; }
}

public class Library
{
    private static double first_operand;
    private static double second_operand;
    private static string operation = null;

    private static TextBlock output;

    private static Func<Item, int> action = (Item item) =>
    {
        switch (item.Mode)
        {
            case Item.ItemMode.Operand:
                output.Text += (int)item.Value;
                break;
            case Item.ItemMode.Operator:              
                string selected = (string)item.Value;
                if (selected == "=")
                {
                    double result = 0.0;
                    if (output.Text.Length > 0)
                    {
                        second_operand = double.Parse(output.Text);
                        switch (operation)
                        {
                            case "/":
                                if (second_operand > 0)
                                {
                                    result = first_operand / second_operand;
                                }
                                break;
                            case "*":
                                result = first_operand * second_operand;
                                break;
                            case "-":
                                result = first_operand - second_operand;
                                break;
                            case "+":
                                result = first_operand + second_operand;
                                break;
                        }
                        output.Text = result.ToString();
                    }
                }
                else if (selected == "<")
                {
                    if (output.Text.Length > 0)
                    {
                        output.Text = output.Text.Substring(0, output.Text.Length - 1);
                    }
                }
                else
                {
                    if (output.Text.Length > 0)
                    {
                        first_operand = int.Parse(output.Text);
                        output.Text = string.Empty;
                        operation = item.Value.ToString();
                    }
                }
                break;
        }
        return 0;
    };

    private List<Item> list = new List<Item>
    {
        new Item { Mode = Item.ItemMode.Operand, Value = 7, Action = action },
        new Item { Mode = Item.ItemMode.Operand, Value = 8, Action = action },
        new Item { Mode = Item.ItemMode.Operand, Value = 9, Action = action },
        new Item { Mode = Item.ItemMode.Operator, Value = "/", Action = action },
        new Item { Mode = Item.ItemMode.Operand, Value = 4, Action = action },
        new Item { Mode = Item.ItemMode.Operand, Value = 5, Action = action },
        new Item { Mode = Item.ItemMode.Operand, Value = 6, Action = action },
        new Item { Mode = Item.ItemMode.Operator, Value = "*", Action = action },
        new Item { Mode = Item.ItemMode.Operand, Value = 1, Action = action },
        new Item { Mode = Item.ItemMode.Operand, Value = 2, Action = action },
        new Item { Mode = Item.ItemMode.Operand, Value = 3, Action = action },
        new Item { Mode = Item.ItemMode.Operator, Value = "-", Action = action },
        new Item { Mode = Item.ItemMode.Operator, Value = "<", Action = action },
        new Item { Mode = Item.ItemMode.Operand, Value = 0, Action = action },
        new Item { Mode = Item.ItemMode.Operator, Value = "=", Action = action },
        new Item { Mode = Item.ItemMode.Operator, Value = "+", Action = action },
    };

    public List<Item> New(ref TextBlock text)
    {
        output = text;
        return list;
    }
}

Step 8

Then in the Solution Explorer select MainPage.xaml

vs2017-library-mainpage

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
	<Grid.RowDefinitions>
		<RowDefinition Height="Auto"/>
		<RowDefinition Height="*"/>
	</Grid.RowDefinitions>
	<TextBlock Grid.Row="0" Name="Output" TextAlignment="Right" FontSize="30" 
		HorizontalAlignment="Stretch" Foreground="{ThemeResource AccentButtonBackground}"/>
	<ItemsControl Grid.Row="1" Name="Display" Loaded="Display_Loaded">
		<ItemsControl.ItemTemplate>
			<DataTemplate>
				<Button Margin="5" Height="50" Width="50" 
					Background="{ThemeResource AccentButtonBackground}" Command="{Binding Command}">
					<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="20"
					Foreground="{ThemeResource AccentButtonForeground}" Text="{Binding Value}"/>
				</Button>
			</DataTemplate>
		</ItemsControl.ItemTemplate>
		<ItemsControl.ItemsPanel>
			<ItemsPanelTemplate>
				<ItemsWrapGrid MaximumRowsOrColumns="4" Orientation="Horizontal"/>
			</ItemsPanelTemplate>
		</ItemsControl.ItemsPanel>
	</ItemsControl>
</Grid>

It should appear as such:

xaml-operator-app
 

Step 11

From the Menu choose View and then Code

vs2017-view-code

Step 12

Once in the Code View, below the public MainPage() { … } the following Code should be entered:

Library library = new Library();

private void Display_Loaded(object sender, RoutedEventArgs e)
{
	Display.ItemsSource = library.New(ref Output);
}

It should then appear as such:

code-operator-app
 

Step 13

That completes the Universal Windows Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-debug

Step 14

Once started the Application should then appear

run-operator-app
 

Step 15

After the Application has started running you can then select any of the Button controls and select either an Operator such as *, +, /, or < to delete a number from the display or any number from 0 to 9 then you can use = to get the answer.

ran-operator-app
 

Step 16

To Exit the application select Stop in Visual Studio

vs2017-stop

Creative Commons License

Universal Windows Platform – ZipFile App

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu locate and select Visual Studio 2017.

vs2017-home

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project

vs2017-new-project

Step 4

Then in New Universal Windows Project you need to select the Target Version to be Windows 10 Creators Update (10.0; Build 15063) and the Minimum Version to be at least Windows 10 Anniversary Update (10.0; Build 14393) or Windows 10 Creators Update (10.0; Build 15063)

vs2017-platform

Step 5

From the Menu choose Project, then Add New Item…

vs2017-add-new-item

Step 6

From the Add New Item choose Visual C# from Installed then choose Code then select Code File and then in the Name as Library.cs and then select Add to add the file to the Project

vs2017-library

Step 7

Then in the Code View for Library.cs the following should be entered:

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.AccessCache;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;

public class ZipItem
{
    public string Name { get; set; }
    public string ActualBytes { get; set; }
    public string CompressedBytes { get; set; }
}

public class Library
{
    public const string extension_all = "*";
    public const string extension_zip = ".zip";
    public const string desc_archive = "Archive";
    public const string desc_file = "File";
    string token = string.Empty;
    StorageItemAccessList access = StorageApplicationPermissions.FutureAccessList;

    private async Task<byte[]> GetByteFromFile(StorageFile storageFile)
    {
        using (IRandomAccessStream stream = await storageFile.OpenReadAsync())
        {
            using (DataReader dataReader = new DataReader(stream))
            {
                byte[] bytes = new byte[stream.Size];
                await dataReader.LoadAsync((uint)stream.Size);
                dataReader.ReadBytes(bytes);
                return bytes;
            }
        }
    }

    private async Task<StorageFile> OpenFileAsync(string extension)
    {
        try
        {
            FileOpenPicker picker = new FileOpenPicker()
            {
                SuggestedStartLocation = PickerLocationId.ComputerFolder
            };
            picker.FileTypeFilter.Add(extension);
            StorageFile open = await picker.PickSingleFileAsync();
            if (open != null)
            {
                return open;
            }
        }
        finally
        {
        }
        return null;
    }

    private async Task<StorageFile> SaveFileAsync(string filename, string extension, string description)
    {
        try
        {
            FileSavePicker picker = new FileSavePicker()
            {
                SuggestedStartLocation = PickerLocationId.DocumentsLibrary,
                DefaultFileExtension = extension,
                SuggestedFileName = filename
            };
            picker.FileTypeChoices.Add(description, new List<string>() { extension });
            StorageFile save = await picker.PickSaveFileAsync();
            if (save != null)
            {
                return save;
            }
        }
        finally
        {
        }
        return null;
    }

    public string Name { get; set; }

    public async Task<List<ZipItem>> List()
    {
        List<ZipItem> results = null;
        StorageFile file = await access.GetFileAsync(token);
        if (file != null)
        {
            using (Stream stream = await file.OpenStreamForReadAsync())
            {
                using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Read))
                {
                    results = new List<ZipItem>();
                    foreach (ZipArchiveEntry entry in archive.Entries)
                    {
                        if (entry.Name != string.Empty)
                        {
                            results.Add(new ZipItem()
                            {
                                Name = entry.Name,
                                CompressedBytes = $"Compressed Size {entry.CompressedLength}",
                                ActualBytes = $"Actual Size {entry.Length}"
                            });
                        }
                    }
                }
            }
        }
        return results;
    }

    public async Task<bool> NewAsync()
    {
        StorageFile file = await SaveFileAsync(desc_archive, extension_zip, desc_archive);
        if (file != null)
        {
            token = access.Add(file);
            Name = file.Name;
            using (Stream stream = await file.OpenStreamForWriteAsync())
            {
                new ZipArchive(stream, ZipArchiveMode.Create);
            }
            return true;
        }
        return false;
    }

    public async Task<List<ZipItem>> OpenAsync()
    {
        StorageFile file = await OpenFileAsync(extension_zip);
        if (file != null)
        {
            Name = file.Name;
            token = access.Add(file);
        }
        return await List();
    }

    public async Task<List<ZipItem>> AddAsync()
    {
        if (!string.IsNullOrEmpty(token))
        {
            StorageFile file = await access.GetFileAsync(token);
            if (file != null)
            {
                StorageFile source = await OpenFileAsync(extension_all);
                if (source != null)
                {
                    using (Stream stream = await file.OpenStreamForWriteAsync())
                    {
                        using (ZipArchive zipArchive = new ZipArchive(stream, ZipArchiveMode.Update))
                        {
                            ZipArchiveEntry existing = zipArchive.GetEntry(source.Name);
                            if (existing != null)
                            {
                                existing.Delete();
                            }
                            ZipArchiveEntry entry = zipArchive.CreateEntry(source.Name);
                            using (Stream entryStream = entry.Open())
                            {
                                byte[] data = await GetByteFromFile(source);
                                entryStream.Write(data, 0, data.Length);
                            }
                        }
                    }
                }
            }
            return await List();
        }
        return null;
    }

    public async void Extract(ZipItem item)
    {
        if (!string.IsNullOrEmpty(token))
        {
            StorageFile file = await access.GetFileAsync(token);
            if (file != null)
            {
                using (Stream stream = await file.OpenStreamForReadAsync())
                {
                    using (ZipArchive zipArchive = new ZipArchive(stream, ZipArchiveMode.Read))
                    {
                        ZipArchiveEntry entry = zipArchive.GetEntry(item.Name);
                        if (entry != null)
                        {
                            StorageFile source = await SaveFileAsync(entry.Name, Path.GetExtension(entry.Name), desc_file);
                            if (source != null)
                            {
                                using (Stream output = await source.OpenStreamForWriteAsync())
                                {
                                    await entry.Open().CopyToAsync(output);
                                    await output.FlushAsync();
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public async Task<List<ZipItem>> RemoveAsync(ZipItem item)
    {
        if (!string.IsNullOrEmpty(token))
        {
            StorageFile file = await access.GetFileAsync(token);
            if (file != null)
            {
                using (Stream stream = await file.OpenStreamForWriteAsync())
                {
                    using (ZipArchive zipArchive = new ZipArchive(stream, ZipArchiveMode.Update))
                    {
                        ZipArchiveEntry entry = zipArchive.GetEntry(item.Name);
                        if (entry != null)
                        {
                            entry.Delete();
                        }
                    }
                }
                return await List();
            }
        }
        return null;
    }
}

Step 8

Then in the Solution Explorer select MainPage.xaml

vs2017-library-mainpage

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Grid.RowDefinitions>
	<RowDefinition Height="Auto"/>
	<RowDefinition Height="*"/>
	<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<CommandBar Grid.Row="2" VerticalAlignment="Bottom">
	<AppBarButton Name="New" Icon="Page2" Label="Open" Click="New_Click"/>
	<AppBarButton Name="Open" Icon="OpenFile" Label="Open" Click="Open_Click"/>
	<AppBarButton Name="Add" Icon="Add" Label="Add" Click="Add_Click"/>
</CommandBar>
<TextBlock Grid.Row="0" Name="Label" Margin="5" Style="{StaticResource SubtitleTextBlockStyle}"/>
<ListBox Grid.Row="1" Name="Display">
	<ListBox.ItemContainerStyle>
		<Style TargetType="ListBoxItem">
			<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
		</Style>
	</ListBox.ItemContainerStyle>
	<ListBox.ItemTemplate>
		<DataTemplate>
			<Grid>
				<Grid.ColumnDefinitions>
					<ColumnDefinition Width="40*"/>
					<ColumnDefinition Width="20*"/>
					<ColumnDefinition Width="20*"/>
					<ColumnDefinition Width="Auto"/>
				</Grid.ColumnDefinitions>
				<Grid Padding="5" Grid.Column="0" Background="{ThemeResource AccentButtonBackground}">
					<TextBlock Text="{Binding Name}" VerticalAlignment="Center"
						Foreground="{ThemeResource AccentButtonForeground}"/>
				</Grid>
				<Grid Padding="5" Grid.Column="1" Background="{ThemeResource AccentButtonForeground}">
					<TextBlock Text="{Binding ActualBytes}" VerticalAlignment="Center"
						Foreground="{ThemeResource AccentButtonBackground}"/>
				</Grid>
				<Grid Padding="5" Grid.Column="2" Background="{ThemeResource AccentButtonForeground}">
					<TextBlock Text="{Binding CompressedBytes}" VerticalAlignment="Center"
						Foreground="{ThemeResource AccentButtonBackground}"/>
				</Grid>
				<StackPanel Grid.Column="3" Orientation="Horizontal">
					<AppBarButton Name="Extract" Icon="SaveLocal" Label="Extract" Tag="{Binding}" Click="Extract_Click"/>
					<AppBarButton Name="Remove" Icon="Remove" Label="Remove" Tag="{Binding}" Click="Remove_Click"/>
				</StackPanel>
			</Grid>
		</DataTemplate>
	</ListBox.ItemTemplate>
</ListBox>

It should appear as such:

xaml-zipfile-app

Step 11

From the Menu choose View and then Code

vs2017-view-code

Step 12

Once in the Code View, below the public MainPage() { … } the following Code should be entered:

Library library = new Library();

private async void New_Click(object sender, RoutedEventArgs e)
{
	if (await library.NewAsync())
	{
		Label.Text = library.Name;
	}
}

private async void Open_Click(object sender, RoutedEventArgs e)
{
	Display.ItemsSource = await library.OpenAsync();
	Label.Text = library.Name;
}

private async void Add_Click(object sender, RoutedEventArgs e)
{
	Display.ItemsSource = await library.AddAsync();
}

private void Extract_Click(object sender, RoutedEventArgs e)
{
	ZipItem item = (ZipItem)((AppBarButton)sender).Tag;
	library.Extract(item);
}

private async void Remove_Click(object sender, RoutedEventArgs e)
{
	ZipItem item = (ZipItem)((AppBarButton)sender).Tag;
	Display.ItemsSource = await library.RemoveAsync(item);
}   

It should then appear as such:

code-zipfile-app

Step 13

That completes the Universal Windows Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-debug

Step 14

Once started the Application should then appear

run-zipfile-app

Step 15

After the Application has started running you can then select New to create a ZIP archive using a FileSavePicker then you need to use Add to add to the archive using the FileOpenPicker. You can view any files in the archive in the ListBox plus you can Extract a file using a FileSavePicker or Remove a file from the archive.

ran-zipfile-app

Step 16

To Exit the application select Stop in Visual Studio

vs2017-stop

Creative Commons License

Universal Windows Platform – JpgInfo App

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu locate and select Visual Studio 2017.

vs2017-home

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project

vs2017-new-project

Step 4

Then in New Universal Windows Project you need to select the Target Version to be Windows 10 Creators Update (10.0; Build 15063) and the Minimum Version to be at least Windows 10 Anniversary Update (10.0; Build 14393) or Windows 10 Creators Update (10.0; Build 15063)

vs2017-platform

Step 5

From the Menu choose Project, then Add New Item…

vs2017-add-new-item

Step 6

From the Add New Item choose Visual C# from Installed then choose Code then select Code File and then in the Name as Library.cs and then select Add to add the file to the Project

vs2017-library

Step 7

Then in the Code View for Library.cs the following should be entered:

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.FileProperties;
using Windows.Storage.Pickers;

public class Library
{
    private async Task<Dictionary<string, string>> GetProperties(StorageFile file)
    {
        Dictionary<string, string> results = new Dictionary<string, string>();
        ImageProperties properties = await file.Properties.GetImagePropertiesAsync();
        results.Add("Name", file.Name);
        foreach (PropertyInfo property in properties.GetType().GetProperties())
        {
            results.Add(property.Name, property.GetValue(properties)?.ToString());
        }
        results.Remove("PeopleNames");
        results.Remove("Keywords");
        return results;
    }

    public async Task<Dictionary<string, string>> OpenAsync()
    {
        try
        {
            FileOpenPicker picker = new FileOpenPicker()
            {
                SuggestedStartLocation = PickerLocationId.PicturesLibrary
            };
            picker.FileTypeFilter.Add(".jpg");
            StorageFile open = await picker.PickSingleFileAsync();
            if (open != null)
            {
                return await GetProperties(open);
            }
        }
        finally
        {

        }
        return null;
    }
}

Step 8

Then in the Solution Explorer select MainPage.xaml

vs2017-library-mainpage

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Grid.RowDefinitions>
	<RowDefinition Height="*"/>
	<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<CommandBar Grid.Row="1" VerticalAlignment="Bottom">
	<AppBarButton Name="Open" Icon="OpenFile" Label="Open" Click="Open_Click"/>
</CommandBar>
<ListBox Grid.Row="0" Name="Display">
	<ListBox.ItemContainerStyle>
		<Style TargetType="ListBoxItem">
			<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
		</Style>
	</ListBox.ItemContainerStyle>
	<ListBox.ItemTemplate>
		<DataTemplate>
			<Grid>
				<Grid.ColumnDefinitions>
					<ColumnDefinition Width="30*"/>
					<ColumnDefinition Width="70*"/>
				</Grid.ColumnDefinitions>
				<Grid Padding="5" Grid.Column="0" Background="{ThemeResource AccentButtonBackground}">
					<TextBlock Text="{Binding Key}" Foreground="{ThemeResource AccentButtonForeground}"/>
				</Grid>
				<Grid Padding="5" Grid.Column="1" Background="{ThemeResource AccentButtonForeground}">
					<TextBlock Text="{Binding Value}" Foreground="{ThemeResource AccentButtonBackground}"/>
				</Grid>
			</Grid>
		</DataTemplate>
	</ListBox.ItemTemplate>
</ListBox>

It should appear as such:

xaml-jpginfo-app

Step 11

From the Menu choose View and then Code

vs2017-view-code

Step 12

Once in the Code View, below the public MainPage() { … } the following Code should be entered:

Library library = new Library();

private async void Open_Click(object sender, RoutedEventArgs e)
{
	Display.ItemsSource = await library.OpenAsync();
}

It should then appear as such:

code-jpginfo-app

Step 13

That completes the Universal Windows Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-debug

Step 14

Once started the Application should then appear

run-jpginfo-app

Step 15

After the Application has started running you can then select Open launch a FileOpenPicker then you need to select a jpg photo to open. Once done then you can view various properties of the image in the ListBox.

ran-jpginfo-app

You can use the following sample JPG

Big Buck Bunny

Step 16

To Exit the application select Stop in Visual Studio

vs2017-stop

Creative Commons License

Universal Windows Platform – PdfView App

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu locate and select Visual Studio 2017.

vs2017-home

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project

vs2017-new-project

Step 4

Then in New Universal Windows Project you need to select the Target Version to be Windows 10 Creators Update (10.0; Build 15063) and the Minimum Version to be at least Windows 10 Anniversary Update (10.0; Build 14393) or Windows 10 Creators Update (10.0; Build 15063)

vs2017-platform

Step 5

From the Menu choose Project, then Add New Item…

vs2017-add-new-item

Step 6

From the Add New Item choose Visual C# from Installed then choose Code then select Code File and then in the Name as Library.cs and then select Add to add the file to the Project

vs2017-library

Step 7

Then in the Code View for Library.cs the following should be entered:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Data.Pdf;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.UI.Popups;
using Windows.UI.Xaml.Media.Imaging;

public class Library
{
    private PdfDocument document = null;

    public void Show(string content, string title)
    {
        IAsyncOperation<IUICommand> command = new MessageDialog(content, title).ShowAsync();
    }

    public async Task<uint> OpenAsync()
    {
        uint pages = 0;
        try
        {
            document = null;
            FileOpenPicker picker = new FileOpenPicker()
            {
                SuggestedStartLocation = PickerLocationId.DocumentsLibrary
            };
            picker.FileTypeFilter.Add(".pdf");
            StorageFile open = await picker.PickSingleFileAsync();
            if (open != null)
            {
                document = await PdfDocument.LoadFromFileAsync(open);
            }
            if (document != null)
            {
                if (document.IsPasswordProtected)
                {
                    Show("Password Protected PDF Document", "PdfView App");
                }
                pages = document.PageCount;
            }
        }
        catch (Exception ex)
        {
            if (ex.HResult == unchecked((int)0x80004005))
            {
                Show("Invalid PDF Document", "PdfView App");
            }
            else
            {
                Show(ex.Message, "PdfView App");
            }
        }
        return pages;
    }

    public async Task<BitmapImage> ViewAsync(uint number)
    {
        BitmapImage source = new BitmapImage();
        if (!(number < 1 || number > document.PageCount))
        {
            uint index = number - 1;
            using (PdfPage page = document.GetPage(index))
            {
                using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
                {
                    await page.RenderToStreamAsync(stream);
                    await source.SetSourceAsync(stream);
                }
            }
        }
        return source;
    }

    public List<int> Numbers(int total)
    {
        return Enumerable.Range(1, total).ToList();
    }
}

Step 8

Then in the Solution Explorer select MainPage.xaml

vs2017-library-mainpage

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<CommandBar VerticalAlignment="Bottom">
	<AppBarButton Name="Open" Icon="OpenFile" Label="Open" Click="Open_Click"/>
</CommandBar>
<Grid>
	<Grid.RowDefinitions>
		<RowDefinition Height="Auto"/>
		<RowDefinition Height="*"/>
	</Grid.RowDefinitions>
	<ComboBox Name="Page" Grid.Row="0" HorizontalAlignment="Stretch" SelectionChanged="Page_SelectionChanged"/>
	<ScrollViewer Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center">
		<Image Name="Display" Stretch="None"/>
	</ScrollViewer>
</Grid>

It should appear as such:

xaml-pdfview-app

Step 11

From the Menu choose View and then Code

vs2017-view-code

Step 12

Once in the Code View, below the public MainPage() { … } the following Code should be entered:

Library library = new Library();

private async void Open_Click(object sender, RoutedEventArgs e)
{
	uint pages = await library.OpenAsync();
	if (pages > 0)
	{
		Page.ItemsSource = library.Numbers(Convert.ToInt32(pages));
		Page.SelectedIndex = 0;
	}
}

private async void Page_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
	uint.TryParse(Page.SelectedItem.ToString(), out uint page);
	Display.Source = await library.ViewAsync(page);
}

It should then appear as such:

code-pdfview-app

Step 13

That completes the Universal Windows Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-debug

Step 14

Once started the Application should then appear

run-pdfview-app

Step 15

After the Application has started running you can then select Open launch a FileOpenPicker then you need to select a pdf document to open. Once done then you can select the ComboBox to choose which page of the document to display but it will start with the first.

ran-pdfview-app

Step 16

To Exit the application select Stop in Visual Studio

vs2017-stop

Creative Commons License