public static class Singleton<T> where T : new() { // Use ConcurrentDictionary for thread safety. private static ConcurrentDictionary<Type, T> _instances = new ConcurrentDictionary<Type, T>(); /// <summary> /// Gets the instance of the Singleton class. /// </summary> public static T Instance { get { // Safely creates the first instance or retrieves the existing instance across threads. return _instances.GetOrAdd(typeof(T), (t) => new T()); } } }
改框架的界面绑定静态并发词典,不同页面之间可以通过该静态词典互相访问成员以及方法。该框架页面只绑定了成员属性到ViewModels,事件处理放在了后台文件,也可以增加RelayCommand到ViewModels中去,感兴趣的朋友可以自己尝试一下。
程序框架整体如下
using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WpfApp1.Utilities { public static class Singleton<T> where T : new() { // Use ConcurrentDictionary for thread safety. private static ConcurrentDictionary<Type, T> _instances = new ConcurrentDictionary<Type, T>(); /// <summary> /// Gets the instance of the Singleton class. /// </summary> public static T Instance { get { // Safely creates the first instance or retrieves the existing instance across threads. return _instances.GetOrAdd(typeof(T), (t) => new T()); } } } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WpfApp1.ViewModels { public class BaseViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string info) { var handler = PropertyChanged; handler?.Invoke(this, new PropertyChangedEventArgs(info)); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Controls; namespace WpfApp1.ViewModels { public class MainViewModel : ViewModels.BaseViewModel { private string _text = "我是主页面"; public string Text { get { return _text; } set { _text = value; OnPropertyChanged("Text"); } } //主页面的内容呈现器 private UserControl _content = new UserControl(); public UserControl Content { get { return _content; } set { _content = value; OnPropertyChanged("Content"); } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WpfApp1.ViewModels { public class User1ViewModel : ViewModels.BaseViewModel { private string _text = "我是User1页面"; public string Text { get { return _text; } set { _text = value; OnPropertyChanged("Text"); } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WpfApp1.ViewModels { public class User2ViewModel : ViewModels.BaseViewModel { private string _text = "我是User2页面"; public string Text { get { return _text; } set { _text = value; OnPropertyChanged("Text"); } } } }
<Window x:Class="WpfApp1.Views.Main" 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:local="clr-namespace:WpfApp1.Views" mc:Ignorable="d" Title="Main" Height="450" Width="800"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="100"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Button Content="User1" Margin="0,0,0,383" Click="Button_Click_User1" /> <Button Content="User2" Margin="0,57,0,326" Click="Button_Click_User2" /> <!--使用内容呈现器实现页面切换--> <ContentPresenter Content="{Binding Content}" Grid.Column="1"/> <TextBlock HorizontalAlignment="Center" Margin="0,140,0,0" TextWrapping="Wrap" Text="{Binding Text}" VerticalAlignment="Top" Height="100" Width="100" RenderTransformOrigin="0.436,0.131"/> </Grid> </Window>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; 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.Shapes; using WpfApp1.Utilities; using WpfApp1.ViewModels; namespace WpfApp1.Views { /// <summary> /// Main.xaml 的交互逻辑 /// </summary> public partial class Main : Window { User1 User1 = new User1(); User2 User2 = new User2(); public Main() { InitializeComponent(); this.DataContext = Singleton<MainViewModel>.Instance; } private void Button_Click_User1(object sender, RoutedEventArgs e) { Singleton<MainViewModel>.Instance.Content = User1; } private void Button_Click_User2(object sender, RoutedEventArgs e) { Singleton<MainViewModel>.Instance.Content = User2; } } }
<UserControl x:Class="WpfApp1.Views.User1" 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:WpfApp1.Views" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" Background="AliceBlue"> <StackPanel VerticalAlignment="Center"> <TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="{Binding Text}" VerticalAlignment="Center"/> <Button Content="用户1界面访问主页面" Click="Button_Click_User1" HorizontalAlignment="Center" VerticalAlignment="Center"/> </StackPanel> </UserControl>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; 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 WpfApp1.Utilities; using WpfApp1.ViewModels; namespace WpfApp1.Views { /// <summary> /// User1.xaml 的交互逻辑 /// </summary> public partial class User1 : UserControl { public User1() { InitializeComponent(); this.DataContext = Singleton<User1ViewModel>.Instance; } private void Button_Click_User1(object sender, RoutedEventArgs e) { Singleton<MainViewModel>.Instance.Text = "用户1界面访问主页面"; } } }
<UserControl x:Class="WpfApp1.Views.User2" 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:WpfApp1.Views" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" Background="Coral"> <StackPanel> <TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="{Binding Text}" VerticalAlignment="Top"/> <Button Content="用户2界面访问用户1界面" Click="Button_Click_User2" HorizontalAlignment="Center" VerticalAlignment="Top"/> </StackPanel> </UserControl>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; 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 WpfApp1.Utilities; using WpfApp1.ViewModels; namespace WpfApp1.Views { /// <summary> /// User2.xaml 的交互逻辑 /// </summary> public partial class User2 : UserControl { public User2() { InitializeComponent(); this.DataContext = Singleton<User2ViewModel>.Instance; } private void Button_Click_User2(object sender, RoutedEventArgs e) { Singleton<User1ViewModel>.Instance.Text = "用户2界面访问用户1界面"; } } }
<Application x:Class="WpfApp1.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApp1" StartupUri="/Views/Main.xaml"> <Application.Resources> </Application.Resources> </Application>