# Create WPF Project

Execute dotnet new wpf -o WPFTutorials or in WPFTutorials directory execute dotnet new wpf .

Open the WPFTutorials using VSCode. There is a problem The name ‘InitializeComponent’ does not exist in the current context in MainWindow.xaml.cs. Becuase the MainWindow is a partial class, the InitializeComponent is automatically generated during the build process from the MainWindow.xaml. This method is crucial for initializing the UI components defined in your XAML.

To Be Solved

# Add WPF UserControl Library

# Cretate and Build UserControl Library

Execute dotnet new wpfusercontrollib -o ControlLibrary . Add SalaryCaculator.xaml and SalaryCaculator.xaml.cs. Then execute dotnet build under the directory ControlLibrary.

SalaryCaculator.xaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<UserControl x:Class="ControlLibrary.SalaryCaculator"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ControlLibrary"
mc:Ignorable="d"
d:DesignHeight="350" d:DesignWidth="400">
<Canvas>
<!-- Labels -->
<TextBlock Text="Basic Salary" Canvas.Left="50" Canvas.Top="30"/>
<TextBlock Text="Bonus" Canvas.Left="50" Canvas.Top="70"/>
<TextBlock Text="Total Salary" Canvas.Left="50" Canvas.Top="150"/>

<!-- Textboxes for Input -->
<TextBox Name="basicSalaryTextBox" Canvas.Left="150" Canvas.Top="30" Width="100"/>
<TextBox Name="bonusTextBox" Canvas.Left="150" Canvas.Top="70" Width="100"/>

<!-- Button to Calculate -->
<Button Name="calculateButton" Content="Calculate" Canvas.Left="50" Canvas.Top="110" Width="200" Click="CalculateButton_Click"/>

<!-- TextBlock for Output -->
<TextBlock Name="totalSalaryTextBlock" Canvas.Left="150" Canvas.Top="150" Width="100"/>
</Canvas>
</UserControl>
SalaryCaculator.xaml.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ControlLibrary;

public partial class SalaryCaculator : UserControl
{
public SalaryCaculator()
{
InitializeComponent();
}

private void CalculateButton_Click(object sender, RoutedEventArgs e)
{
try
{
// Get the inputs from the textboxes
double basicSalary = Convert.ToDouble(basicSalaryTextBox.Text);
double bonus = Convert.ToDouble(bonusTextBox.Text);

// Calculate the total salary
double totalSalary = basicSalary + bonus;

// Display the result
totalSalaryTextBlock.Text = "Total: " + totalSalary.ToString("C");
}
catch (Exception)
{
MessageBox.Show("Invalid input. Please enter valid numbers.");
}
}
}

# Add to WPFTutorials

Add reference in the WPFTutorials.csproj.

WPFTutorials.csproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
</PropertyGroup>

<ItemGroup>
<!--add reference of UserControl Library-->
<Reference Include="OpenHardwareMonitorLib">
<HintPath>D:\study\csharp\ControlLibrary\bin\Debug\net8.0-windows\ControlLibrary.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

# Usage in WPFTutorials

Add namespace xmlns:control="clr-namespace:ControlLibrary;assembly=ControlLibrary" in MainWindow.xaml and use with namespace prefix <control:SalaryCaculator Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="2"/> .

MainWindow.xaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<Window x:Class="WPFTutorials.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:control="clr-namespace:ControlLibrary;assembly=ControlLibrary"
xmlns:local="clr-namespace:WPFTutorials" mc:Ignorable="d" Title="MainWindow" Height="600" Width="800">
<Window.Resources>
<local:Human x:Key="human" Name="Babb" Child="babb chen"/>
<sys:String x:Key="stringHello">Hello WPF!</sys:String>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

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

<!-- <Rectangle Width="100" Height="80" Stroke="Black" Fill="Blue"/> -->
<!-- <Path Data="M 0,0 L 200,10 L 100,200 Z" Stroke="Black" Fill="Red"/> -->
<Button Grid.Row="0" Grid.Column="0" Width="120" Height="30" Click="Button_Click">
<Button.Content>
<Rectangle Width="20" Height="20" Stroke="DarkGreen">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<!-- <LinearGradientBrush.StartPoint>
<Point X="0" Y="0"/>
</LinearGradientBrush.StartPoint>
<LinearGradientBrush.EndPoint>
<Point X="1" Y="1"/>
</LinearGradientBrush.EndPoint> -->
<!-- <LinearGradientBrush.GradientStops>
<GradientStopCollection> -->
<GradientStop Offset="0.2" Color="Orange"/>
<GradientStop Offset="0.7" Color="OrangeRed"/>
<GradientStop Offset="1" Color="Red"/>
<!-- </GradientStopCollection>
</LinearGradientBrush.GradientStops> -->
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Button.Content>
</Button>

<TextBlock Grid.Row="0" Grid.Column="1" Height="24" Width="120" TextAlignment="Center"
Background="LightBlue" Text="{StaticResource ResourceKey=stringHello}"/>

<Grid Grid.Row="1" Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="24"/>
<RowDefinition Height="4"/>
<RowDefinition Height="24"/>
</Grid.RowDefinitions>
<TextBlock x:Name="textBlock" Text="{Binding ElementName=slider, Path=Value}"/>
<Slider x:Name="slider" Grid.Row="2" Minimum="0" Maximum="100" Value="50"/>
</Grid>

<!--The Click="EventOwnerButton_Click" equals to this.eventOwnerButton.Click += new RoutedEventHandler(this.EventOwnerButton_Click); in MainWindow.xaml.cs
-->
<!-- <Button x:Name="eventOwnerButton" Content="EventOwnerButton" Grid.Row="1" Grid.Column="1" Width="120" Height="30" Click="EventOwnerButton_Click"/> -->
<Button x:Name="eventOwnerButton" Content="EventOwnerButton" Grid.Row="1" Grid.Column="1" Width="120" Height="30" />

<control:SalaryCaculator Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="2"/>
</Grid>
</Window>
MainWindow.xaml.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
using System.ComponentModel;
using System.Globalization;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPFTutorials;

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();


this.eventOwnerButton.Click += new RoutedEventHandler(this.EventOwnerButton_Click);

// Grid? grid = this.Content as Grid;
// if (grid?.Children[0] is Button button)
// {
// button.Content = "WPF";
// }
}

private void Button_Click(object sender, RoutedEventArgs e)
{
Human? human = this.FindResource("human") as Human;
MessageBox.Show(human?.Child?.Name);
}


private void EventOwnerButton_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hello WPF!");
}
}

[TypeConverter(typeof(NameToHumanTypeConverter))]
public class Human
{
public string? Name { get; set; }
public Human? Child { get; set; }
}

public class NameToHumanTypeConverter : TypeConverter
{
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
string? name = value.ToString();
Human child = new()
{
Name = name
};
return child;
}
}

# Run the WPF Project

Execute dotnet run under the directory WPFTutorials.

Edited on