WPF Prism.Wpf RegionManager
Install-Package Prism.Wpf;
Install-Package Prism.DryIOC;
<Window x:Class="WpfApp28.Views.MainWin" 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:WpfApp28.Views" WindowState="Maximized" mc:Ignorable="d" Title="MainWin" Height="450" Width="800" prism:ViewModelLocator.AutoWireViewModel="True" > <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <TextBlock Text="{Binding MainStatus}" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" FontSize="30"/> <ContentControl Grid.Row="1" Grid.Column="0" prism:RegionManager.RegionName="DgRegion"/> <ContentControl Grid.Row="1" Grid.Column="1" prism:RegionManager.RegionName="ImageRegion"/> </Grid> </Window> using System.Configuration; using System.Data; using System.Windows; using WpfApp28.Services; using WpfApp28.ViewModels; using WpfApp28.Views; namespace WpfApp28 { /// <summary> /// Interaction logic for App.xaml /// </summary> public partial class App : PrismApplication { protected override Window CreateShell() { return Container.Resolve<MainWin>(); } protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.Register<IIDService, IDService>(); containerRegistry.Register<INameService, NameService>(); containerRegistry.Register<IISBNService,ISBNService>(); containerRegistry.RegisterForNavigation<DgView, DgViewModel>("DgView"); containerRegistry.RegisterForNavigation<ImageView, ImageViewModel>("ImgView"); } protected override void OnInitialized() { base.OnInitialized(); //var mainWin=Container.Resolve<MainWin>(); //mainWin?.Show(); var regionManager = Container.Resolve<IRegionManager>(); regionManager.RequestNavigate("DgRegion", "DgView"); regionManager.RequestNavigate("ImageRegion", "ImgView"); } } }
//MainWin.xaml <Window x:Class="WpfApp28.Views.MainWin" 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:WpfApp28.Views" WindowState="Maximized" mc:Ignorable="d" Title="MainWin" Height="450" Width="800" prism:ViewModelLocator.AutoWireViewModel="True" > <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <TextBlock Text="{Binding MainStatus}" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" FontSize="30"/> <ContentControl Grid.Row="1" Grid.Column="0" prism:RegionManager.RegionName="DgRegion"/> <ContentControl Grid.Row="1" Grid.Column="1" prism:RegionManager.RegionName="ImageRegion"/> </Grid> </Window> //MainWinViewModel.cs using System; using System.Collections.Generic; using System.Text; namespace WpfApp28.ViewModels { public class MainWinViewModel:BindableBase { UInt128 idx = 0; public MainWinViewModel() { MainStatus = $"{++idx}_{Guid.NewGuid():N}_" + $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}"; Task.Run(() => { InitTimer(); }); } private void InitTimer() { System.Timers.Timer tmr=new System.Timers.Timer(); tmr.Interval = 1000; tmr.Elapsed += Tmr_Elapsed; tmr.Start(); } private void Tmr_Elapsed(object? sender, System.Timers.ElapsedEventArgs e) { MainStatus = $"{++idx}_{Guid.NewGuid():N}_" + $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}"; } private string mainStatus; public string MainStatus { get { return mainStatus; } set { SetProperty(ref mainStatus, value); } } } } //App.xaml <prism:PrismApplication x:Class="WpfApp28.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApp28" xmlns:prism="http://prismlibrary.com/"> </prism:PrismApplication> //App.xaml.cs using System.Configuration; using System.Data; using System.Windows; using WpfApp28.Services; using WpfApp28.ViewModels; using WpfApp28.Views; namespace WpfApp28 { /// <summary> /// Interaction logic for App.xaml /// </summary> public partial class App : PrismApplication { protected override Window CreateShell() { return Container.Resolve<MainWin>(); } protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.Register<IIDService, IDService>(); containerRegistry.Register<INameService, NameService>(); containerRegistry.Register<IISBNService,ISBNService>(); containerRegistry.RegisterForNavigation<DgView, DgViewModel>("DgView"); containerRegistry.RegisterForNavigation<ImageView, ImageViewModel>("ImgView"); } protected override void OnInitialized() { base.OnInitialized(); //var mainWin=Container.Resolve<MainWin>(); //mainWin?.Show(); var regionManager = Container.Resolve<IRegionManager>(); regionManager.RequestNavigate("DgRegion", "DgView"); regionManager.RequestNavigate("ImageRegion", "ImgView"); } } } //DgView.xaml <UserControl x:Class="WpfApp28.Views.DgView" 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:prism="http://prismlibrary.com/" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" prism:ViewModelLocator.AutoWireViewModel="True" xmlns:local="clr-namespace:WpfApp28.Views" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> <DataGrid ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.CacheLengthUnit="Item" VirtualizingPanel.CacheLength="2,2" ScrollViewer.IsDeferredScrollingEnabled="True" ScrollViewer.CanContentScroll="True" AutoGenerateColumns="True" FontSize="20" CanUserAddRows="False"> </DataGrid> </Grid> </UserControl> //DgView.xaml.cs using System; using System.Collections.Generic; 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; using WpfApp28.ViewModels; namespace WpfApp28.Views { /// <summary> /// Interaction logic for DgView.xaml /// </summary> public partial class DgView : UserControl { public DgView() { InitializeComponent(); this.Loaded += async (s, e) => { var vm = this.DataContext as DgViewModel; if (vm != null) { await vm.InitBooksCollection(); } }; } } } //DgViewModel.cs using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Configuration; using System.Text; using WpfApp28.Models; using WpfApp28.Services; namespace WpfApp28.ViewModels { public class DgViewModel:BindableBase { IIDService idService; INameService nameService; IISBNService isbnService; public DgViewModel(IIDService idServiceValue,INameService nameServiceValue, IISBNService isbnServiceValue) { idService = idServiceValue; nameService = nameServiceValue; isbnService = isbnServiceValue; } public async Task InitBooksCollection() { BooksCollection = new ObservableCollection<Book>(); List<Book> booksList= new List<Book>(); for(int i=1;i<1000001;i++) { booksList.Add(new Book() { Id = idService.GetID(), Name = nameService.GetName(), ISBN = isbnService.GetISBN(), Title = $"Title_{i}", Topic = $"Topic_{i}" }); if (i % 10000 == 0) { await PopulateBooksCollectionAsync(booksList); } } if(booksList.Any()) { await PopulateBooksCollectionAsync(booksList); } } private async Task PopulateBooksCollectionAsync(List<Book> booksList) { var tempList = booksList.ToList(); booksList.Clear(); await System.Windows.Application.Current.Dispatcher.InvokeAsync(async () => { foreach (var bk in tempList) { BooksCollection.Add(bk); } }, System.Windows.Threading.DispatcherPriority.Background); } private ObservableCollection<Book> booksCollection; public ObservableCollection<Book> BooksCollection { get { return booksCollection; } set { SetProperty(ref booksCollection, value); } } } } //ImageView.xaml <UserControl x:Class="WpfApp28.Views.ImageView" 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:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" xmlns:local="clr-namespace:WpfApp28.Views" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> <Grid.Background> <ImageBrush ImageSource="{Binding ImgSource}" Stretch="Uniform"/> </Grid.Background> <TextBlock Text="{Binding ImgUrl}" HorizontalAlignment="Stretch" VerticalAlignment="Center" Foreground="Red" FontSize="50" TextWrapping="Wrap"/> </Grid> </UserControl> //ImageViewModel.cs using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Windows.Media; using System.Windows.Media.Imaging; namespace WpfApp28.ViewModels { public class ImageViewModel : BindableBase { List<string> imgsList = new List<string>(); int imgsCount = 0; int imgIdx = 0; public ImageViewModel() { InitImgs(); Task.Run(() => { InitTimer(); }); } private void InitTimer() { System.Timers.Timer tmr=new System.Timers.Timer(); tmr.Interval = 1000; tmr.Elapsed += Tmr_Elapsed; tmr.Start(); } private void Tmr_Elapsed(object? sender, System.Timers.ElapsedEventArgs e) { System.Windows.Application.Current.Dispatcher.Invoke(new Action(() => { ImgUrl = System.IO.Path.GetFullPath(imgsList[(++imgIdx) % imgsCount]); ImgSource = GenImageSourceViaUrl(ImgUrl); })); } private void InitImgs() { string imgDir = @"../../../Images"; if (!Directory.Exists(imgDir)) { return; } imgsList = Directory.GetFiles(imgDir).ToList(); if (imgsList == null || !imgsList.Any()) { return; } imgsCount = imgsList.Count; ImgUrl = System.IO.Path.GetFullPath(imgsList[0]); ImgSource = GenImageSourceViaUrl(ImgUrl); } private ImageSource GenImageSourceViaUrl(string imgUrl) { BitmapImage bmi = new BitmapImage(); if(!File.Exists(imgUrl)) { return bmi; } bmi.BeginInit(); bmi.UriSource=new Uri(imgUrl,UriKind.RelativeOrAbsolute); bmi.EndInit(); if(bmi.CanFreeze) { bmi.Freeze(); } return bmi; } private ImageSource imgSource; public ImageSource ImgSource { get { return imgSource; } set { SetProperty(ref imgSource, value); } } private string imgUrl; public string ImgUrl { get { return imgUrl; } set { SetProperty(ref imgUrl, value); } } } } //Service.cs using System; using System.Collections.Generic; using System.Text; namespace WpfApp28.Services { public interface IIDService { int GetID(); } public class IDService : IIDService { int idx = 0; public int GetID() { return Interlocked.Increment(ref idx); } } public interface INameService { string GetName(); } public class NameService : INameService { int idx = 0; public string GetName() { return $"Name_{Interlocked.Increment(ref idx)}"; } } public interface IISBNService { string GetISBN(); } public class ISBNService:IISBNService { int idx = 0; public string GetISBN() { return $"ISBN_{Interlocked.Increment(ref idx)}_{Guid.NewGuid():N}"; } } } //Book.cs using System; using System.Collections.Generic; using System.Text; namespace WpfApp28.Models { public class Book { public int Id { get; set; } public string Name { get; set; } public string ISBN { get; set; } public string Title { get;set; } public string Topic { get; set; } } }