We can use WPF controls in Winforms applications if we want. In some cases, we can easily design a control as WPF, which would be very problem to make in winforms. That's why we can host as a solution.
Before starting the application, I need to specify, the application I will make in this article will proceed through the dotnet CLI. So, I am not going to use Visual Studio in this tutorial.
First, I will create a sample project. I created one empty folder named ProjectExample. I opened cmd terminal in this directory.
I am creating a solution file for the project with the following command:
dotnet new sln -n "ProjectSolution"
After that, I'm creating a windows forms application called test:
dotnet new winforms -n test
Now it's time to create a WPF user control class. For this I write the following command:
dotnet new wpfusercontrollib -n "wpfcontrol"
After this process, I need to add both applications to the solution file:
dotnet sln ProjectSolution.sln add ./test/test.csproj
dotnet sln ProjectSolution.sln add ./wpfcontrol/wpfcontrol.csproj
Then I add the reference of the wpf user control to the project named test:
dotnet add test/test.csproj reference wpfcontrol/wpfcontrol.csproj
We have finished the settings on the command line. Open the project named test with any editor or ide. I am using VS Code. In order to use the WPF UserControl as a host in Winforms, we must first set the following in the test.csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\wpfcontrol\wpfcontrol.csproj" />
</ItemGroup>
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWpf>true</UseWpf>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>
Let's run our project for testing purposes and only a blank form window will appear on the screen.
../test> dotnet run
I added a button to the UserControl1.xaml file:
<UserControl x:Class="wpfcontrol.UserControl1"
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:wpfcontrol"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Button x:Name="btn1">click the button</Button>
</Grid>
</UserControl>
We need to show this control on winforms. Let's open the Form1.Designer.cs file in the test project. First we need to include the two libraries:
namespace test;
using wpfcontrol;
using System.Windows.Forms.Integration;
partial class Form1
{
...
Next, we integrate the wpf control into winforms using elementhost:
...
UserControl1 test;
private void InitializeComponent()
{
...
ElementHost elementHost = new ElementHost();
test = new UserControl1();
elementHost.Child = test;
this.Controls.Add(elementHost);
...
It's time to run the project and the result is as expected:
If we want to interact with the button in the UserControl, first of all, a public property named Button is defined in the UserControl1 class:
namespace wpfcontrol
{
...
public partial class UserControl1 : UserControl
{
public Button Button1 {get {return btn1; }}
public UserControl1()
{
InitializeComponent();
}
...
Then we go to the test project and reach the control button with the property we defined and subscribe to click event as follows:
...
test = new UserControl1();
elementHost.Child = test;
this.Controls.Add(elementHost);
this.test.Button1.Click += (o, e) =>
{
this.test.Button1.Background = System.Windows.Media.Brushes.Aqua;
};
}
...
If we run the project again and click the button, the color of the button should change as we want:
No comments:
Post a Comment