# 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 > <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" /> <TextBox Name ="basicSalaryTextBox" Canvas.Left ="150" Canvas.Top ="30" Width ="100" /> <TextBox Name ="bonusTextBox" Canvas.Left ="150" Canvas.Top ="70" Width ="100" /> <Button Name ="calculateButton" Content ="Calculate" Canvas.Left ="50" Canvas.Top ="110" Width ="200" Click ="CalculateButton_Click" /> <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 { double basicSalary = Convert.ToDouble(basicSalaryTextBox.Text); double bonus = Convert.ToDouble(bonusTextBox.Text); double totalSalary = basicSalary + bonus; 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 > <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); } 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.