This article is reproduced from a reprint.
Original author: RyzenAdorer
Original title: .NET Core 3 WPF MVVM Framework Prism Series – Data Binding
Original link: https://www.cnblogs.com/ryzen/p/11905866.html
1. Installing Prism
- Using the Package Manager Console
Install-Package Prism.Unity -Version 7.2.0.1367
You can also omit -Version 7.2.0.1367 to get the latest version.
- Using NuGet Package Manager for Solution

You might wonder why installing Prism is related to Prism.Unity. We know Unity is an IOC container, and Prism itself supports IOC. Currently, the official support includes several IOC containers:

-
- Since Unity is from Microsoft and supports Prism’s modularity, I recommend using Prism.Unity. In the official documentation, Prism 7 does not support Prism.Mef, and Prism 7.1 will not support Prism.Autofac.
-
- Installing Prism.Unity already includes all core Prism libraries, with the following architecture:

2. Implementing Data Binding
First, create the Views folder and the ViewModels folder. Place MainWindow in the Views folder, then create the MainWindowViewModel class in the ViewModels folder, as shown below:

The XAML code is as follows:
<Window
x:Class="PrismSample.Views.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:prism="http://prismlibrary.com/"
xmlns:local="clr-namespace:PrismSample"
mc:Ignorable="d"
Title="MainWindow"
Height="450"
Width="800"
prism:ViewModelLocator.AutoWireViewModel="True"
>
<StackPanel>
<TextBox
Text="{Binding Text}"
Margin="10"
Height="100"
FontSize="50"
Foreground="Black"
BorderBrush="Black"
/>
<button
Height="100"
Width="300"
Content="Click Me"
FontSize="50"
Command="{Binding ClickCommnd}"
/>
</StackPanel>
</Window>
The ViewModel code is as follows:
using Prism.Commands;
using Prism.Mvvm;
namespace PrismSample.ViewModels
{
public class MainWindowViewModel:BindableBase
{
private string _text;
public string Text
{
get { return _text; }
set { SetProperty(ref _text, value); }
}
private DelegateCommand _clickCommnd;
public DelegateCommand ClickCommnd =>
_clickCommnd ?? (_clickCommnd = new DelegateCommand(ExecuteClickCommnd));
void ExecuteClickCommnd()
{
this.Text = "Click Me!";
}
public MainWindowViewModel()
{
this.Text = "Hello Prism!";
}
}
}
Run the application:

Click the "Click Me" button:

As you can see, we have successfully achieved data binding with Prism, and the View and ViewModel are perfectly separated.
Now another question arises: what if we don’t want to strictly follow Prism’s convention of placing Views and ViewModels in the Views and ViewModels folders? Or if the naming conventions in our project are different? In such cases, we need to use other methods:
- Changing the Naming Convention
If the company’s naming conventions are very strict, causing the project structure to look like this (you might as well resign from such a company):

First, we need to introduce Prism in App, change Application to prism:PrismApplication and remove StartupUri.
The XAML code is as follows:
<prism:PrismApplication
x:Class="PrismSample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
xmlns:local="clr-namespace:PrismSample"
>
<Application.Resources> </Application.Resources>
</prism:PrismApplication>
The code-behind for App.cs is as follows:
using Prism.Unity;
using Prism.Ioc;
using Prism.Mvvm;
using System.Windows;
using PrismSample.Viewsb;
using System;
using System.Reflection;
namespace PrismSample
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : PrismApplication
{
// Set the startup page
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
}
// Configure naming conventions
protected override void ConfigureViewModelLocator()
{
base.ConfigureViewModelLocator();
ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver((viewType) =>
{
var viewName = viewType.FullName.Replace(".Viewsb.", ".ViewModelsa.OhMyGod.");
var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName;
var viewModelName = $"{viewName}Test, {viewAssemblyName}";
return Type.GetType(viewModelName);
});
}
}
}
The key lines are these two:
".Viewsb." represents the namespace of the folder containing the View, and ".ViewModelsa.OhMyGod." represents the namespace of the ViewModel.
var viewName = viewType.FullName.Replace(".Viewsb.", ".ViewModelsa.OhMyGod.");
Test represents the suffix of the ViewModel.
var viewModelName = $"{viewName}Test, {viewAssemblyName}";
- Custom ViewModel Registration
Let’s create a custom class Foo, with the following code:
using Prism.Commands;
using Prism.Mvvm;
namespace PrismSample
{
public class Foo:BindableBase
{
private string _text;
public string Text
{
get { return _text; }
set { SetProperty(ref _text, value); }
}
public Foo()
{
this.Text = "Foo";
}
private DelegateCommand _clickCommnd;
public DelegateCommand ClickCommnd =>
_clickCommnd ?? (_clickCommnd = new DelegateCommand(ExecuteClickCommnd));
void ExecuteClickCommnd()
{
this.Text = "Oh My God!";
}
}
}
Modify the App.cs code:
protected override void ConfigureViewModelLocator()
{
base.ConfigureViewModelLocator();
ViewModelLocationProvider.Register<MainWindow, Foo>();
//ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver((viewType) =>
//{
// var viewName = viewType.FullName.Replace(".Viewsb.", ".ViewModelsa.OhMyGod.");
// var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName;
// var viewModelName = $"{viewName}Test, {viewAssemblyName}";
// return Type.GetType(viewModelName);
//});
}
Run the application:

Click the button:

Even if we don’t comment out the code that changes the naming convention, the result is still the same. Therefore, we can conclude that this direct registration method (without reflection) has a higher priority. The official documentation also indicates that this method is more efficient.
The official documentation provides four methods, and the other three registration methods are as follows:
ViewModelLocationProvider.Register(typeof(MainWindow).ToString(), typeof(MainWindowTest));
ViewModelLocationProvider.Register(typeof(MainWindow).ToString(), () => Container.Resolve<Foo>());
ViewModelLocationProvider.Register<MainWindow>(() => Container.Resolve<Foo>());