WPF使用并发词典ConcurrentDictionary实现MVVM(一)- 绑定成员

    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());
            }
        }
    }
}
Singleton.cs
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));
        }
    }
}
BaseViewModel.cs
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"); }
        }
    }
}
MainViewModel.cs
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");
            }
        }
    }
}
User1ViewModel.cs
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");
            }
        }
    }
}
User2ViewModel.cs
<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>
Main.xaml
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;
        }
    }
}
Main.xaml.cs
<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>
User1.xaml
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界面访问主页面";
        }
    }
}
User.xaml.cs
<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>
User2.xaml
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界面";
        }
    }
}
User2.xaml.cs
<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>
App.xaml

 

posted @ 2022-08-09 17:02  阿坦  阅读(132)  评论(0)    收藏  举报