C#中使用 Lazy<T>在WPF中实现单例模式

Lazy是延迟对象,通过它可以延迟创建T对象,也就是说,虽然已经声明了对象,但是实际上只有在使用T对象的时候,才会去创建这个对象。

在WPF中, 公共方法 可以写在单独的一个类中, 各个viewmodel等需要的时候再去使用Lazy调用.

例如
建立公共类appData

using GalaSoft.MvvmLight;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DAL;

namespace ShenhuaSQLite
{
    public class AppData: ObservableObject
    {
        public AppData()
        {

        }

        public static AppData Instance = new Lazy<AppData>(() => new AppData()).Value;

        private string systemName = "Zg上位机测试";

        public string SystemName
        {
            get { return systemName; }
            set { systemName = value; }
        }

        private SysAdmins sysAdmins = new SysAdmins();

        public SysAdmins CurrentUser
        {
            get { return sysAdmins; }
            set { sysAdmins = value;  RaisePropertyChanged(); }
        }

        /// 
        /// 主窗体
        /// 
        public MainWindow MainWindow { get; set; } = null;

        /// 
        /// 显示或隐藏遮罩层
        /// 
        /// 
        public void ShowMarkLayer(bool isMark)
        {
            if (MainWindow == null) return;
            //MainWindow.markLayer.Visibility = isMark ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden;
        }

    }
}

在登录窗体中, 可以在构造函数中实例化lazy, 实现调用appData中所有属性和方法. 这有些类似于博途中的多重背景数据块.

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using DAL;

namespace ShenhuaSQLite.ViewModel
{
    public class LoginViewModel : ViewModelBase
    {
        public AppData appData { get; private set; } = AppData.Instance;

        public LoginViewModel()
        {
            this.appData.CurrentUser.LoginName = "ZG";
            this.appData.CurrentUser.LoginPwd = "123";
        }

        public RelayCommand<Window> LoginCommand2 //只写get Return
        {
            get
            {
                return new RelayCommand<Window>((arg) =>
                {
                    SysAdminsProvider sysAdminsProvider = new SysAdminsProvider();
                    //MemberProvider memberProvider = new MemberProvider();
                    var list = sysAdminsProvider.Select();
                    var user = list.FirstOrDefault(
                        u => u.LoginName == appData.CurrentUser.LoginName
                        && u.LoginPwd == appData.CurrentUser.LoginPwd) ; //u为数据库对象

                    if (user == null)
                    {
                        MessageBox.Show("用户名或密码错误!");
                    }
                    else
                    {
                        MainWindow mainWindow = new MainWindow();
                        mainWindow.Show();
                        arg.Close();
                    }
                });
            }
        }


    }
}

C#中使用 Lazy<T>在WPF中实现单例模式_第1张图片

using DAL;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using ShenhuaSQLite.Windows;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace ShenhuaSQLite.ViewModel
{
    public class ActualDataViewModel:ViewModelBase
    {
        public AppData appData { get; private set; } = AppData.Instance;

        public ActualDataViewModel()
        {
            Task.Run(() =>
            {
                ActualDatas = new ActualDataProvider().Select();
            });
        }

        private List<ActualData> actualDatas = new List<ActualData>();

        public List<ActualData> ActualDatas
        {
            get { return actualDatas; }
            set { actualDatas = value; RaisePropertyChanged(); }
        }

        /// 
        /// 打开添加新记录对话框
        /// 
        public RelayCommand OpenAddActulDataWindowCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    var window = new AddActualDataWindow();
                    window.ShowDialog();
                    //刷新数据
                    ActualDatas = new ActualDataProvider().Select();
                });
            }
        }

        public RelayCommand<object> DeleteActualDataCommand
        {
            get
            {
                return new RelayCommand<object>((arg) =>
                {
                    Task.Run(() => 
                    {
                        if (!(arg is ActualData model)) return;
                        var actdata = new ActualDataProvider().Select().FindAll(t => t.Id == model.Id);
                        //if (actdata != null && actdata.Count > 0) { MessageBox.Show("当前类型已有引用"); return; }
                        var count = new ActualDataProvider().Delete(model);
                        if (count > 0) MessageBox.Show("操作成功");
                        //刷新数据
                        ActualDatas = new ActualDataProvider().Select();
                    });

                });
            }
        }

        //让前端监听到数据的变化 继承于Collection, INotifyCollectionChanged, INotifyPropertyChanged
        private ObservableCollection<ActualData> actualcount = new ObservableCollection<ActualData>();
        /// 
        /// 所有物资类型
        /// 
        public ObservableCollection<ActualData> Actualcount
        {
            get
            {
                return actualcount;
            }
            set
            {
                actualcount = value;
                RaisePropertyChanged(); //属于ObservableObject
            }
        }
    }
}

using GalaSoft.MvvmLight;
using LiveCharts;
using LiveCharts.Wpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ShenhuaSQLite.ViewModel
{
    public class IndexViewModel:ViewModelBase
    {
        public AppData appData { get; private set; } = AppData.Instance;

        public IndexViewModel()
        {

        }

        private IChartValues actualChartValues = new ChartValues<double>();

        public IChartValues ActualChartValues
        {
            get { return actualChartValues; }
            set { actualChartValues = value; RaisePropertyChanged(); }
        }

        private List<string> acualLabels;

        public List<string> AcualLabels
        {
            get { return acualLabels; }
            set { acualLabels = value; RaisePropertyChanged(); }
        }

        /// 
        /// 饼图
        /// 
        public SeriesCollection PieSeries { get; set; } = new SeriesCollection();

        private IChartValues memberChartValues = new ChartValues<int>();

        /// 
        /// 用户操作的流水数据的报表值
        /// 
        public IChartValues MemberChartValues
        {
            get { return memberChartValues; }
            set { memberChartValues = value; RaisePropertyChanged(); }
        }

        /// 
        /// 曲线报表
        /// 
        public SeriesCollection LineSeries { get; set; } = new SeriesCollection();
        /// 
        /// 曲线报表的标签
        /// 
        public AxesCollection LineAxis { get; set; } = new AxesCollection();

    }
}

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using DAL;

namespace ShenhuaSQLite.ViewModel
{
    public class LoginViewModel : ViewModelBase
    {
        public AppData appData { get; private set; } = AppData.Instance;

        public LoginViewModel()
        {
            this.appData.CurrentUser.LoginName = "ZG";
            this.appData.CurrentUser.LoginPwd = "123";
        }

        public RelayCommand<Window> LoginCommand2 //只写get Return
        {
            get
            {
                return new RelayCommand<Window>((arg) =>
                {
                    SysAdminsProvider sysAdminsProvider = new SysAdminsProvider();
                    //MemberProvider memberProvider = new MemberProvider();
                    var list = sysAdminsProvider.Select();
                    var user = list.FirstOrDefault(
                        u => u.LoginName == appData.CurrentUser.LoginName
                        && u.LoginPwd == appData.CurrentUser.LoginPwd) ; //u为数据库对象

                    if (user == null)
                    {
                        MessageBox.Show("用户名或密码错误!");
                    }
                    else
                    {
                        MainWindow mainWindow = new MainWindow();
                        mainWindow.Show();
                        arg.Close();
                    }
                });
            }
        }


    }
}

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using ShenhuaSQLite.View;
using System.Windows.Controls;

namespace ShenhuaSQLite.ViewModel
{
    /// 
    /// This class contains properties that the main View can data bind to.
    /// 
    /// Use the mvvminpc snippet to add bindable properties to this ViewModel.
    /// 
    /// 
    /// You can also use Blend to data bind with the tool's support.
    /// 
    /// 
    /// See http://www.galasoft.ch/mvvm
    /// 
    /// 
    public class MainViewModel : ViewModelBase
    {
        public AppData appData { get; private set; } = AppData.Instance;
        public MainViewModel()
        {

        }

        /// 
        /// 判断传入参数是否为RadioButton,经过选择判断切换到相应页面
        /// 使用container.Content接收用户控件页面
        /// 
        public RelayCommand<RadioButton> SelectViewCommand
        {
            get
            {

                return new RelayCommand<RadioButton>((t) =>
                {
                    if (!(t is RadioButton button))
                    {
                        return;
                    }
                    if (string.IsNullOrEmpty(button.Content.ToString()))
                    {
                        return;
                    }


                    switch (t.Content.ToString())// button 可以代替
                    {
                        case "首页": AppData.Instance.MainWindow.container.Content = new ActualDataView(); break;
                        case "控制流程": AppData.Instance.MainWindow.container.Content = new ReportDataView(); break;
                        //case "硬件组态": AppData.Instance.MainWindow.container.Content = new CargoView(); break;
                        case "历史趋势": AppData.Instance.MainWindow.container.Content = new IndexView(); break;
                        case "数据报表": AppData.Instance.MainWindow.container.Content = new ActualDataView(); break;
                        //case "参数设置": AppData.Instance.MainWindow.container.Content = new UnitTypeView(); break;
                        default:
                            break;
                    }
                });
            }
        }
    }
}
/*
  In App.xaml:
  
      
  
  
  In the View:
  DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"

  You can also use Blend to do all this with the tool's support.
  See http://www.galasoft.ch/mvvm
*/

using CommonServiceLocator;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
//using Microsoft.Practices.ServiceLocation;

namespace ShenhuaSQLite.ViewModel
{
    /// 
    /// This class contains static references to all the view models in the
    /// application and provides an entry point for the bindings.
    /// 
    public class ViewModelLocator
    {
        /// 
        /// Initializes a new instance of the ViewModelLocator class.
        /// 
        public ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

            if (ViewModelBase.IsInDesignModeStatic)
            {
                // Create design time view services and models
                SimpleIoc.Default.Register();
            }
            else
            {
                // Create run time view services and models
                SimpleIoc.Default.Register();
            }

            SimpleIoc.Default.Register<MainViewModel>();
            SimpleIoc.Default.Register<LoginViewModel>();
            SimpleIoc.Default.Register<ReportDataViewModel>();
            SimpleIoc.Default.Register<ActualDataViewModel>();
            SimpleIoc.Default.Register<IndexViewModel>();
        }

        public MainViewModel Main
        {
            get
            {
                return ServiceLocator.Current.GetInstance<MainViewModel>();
            }
        }

        public LoginViewModel Login
        {
            get
            {
                return ServiceLocator.Current.GetInstance<LoginViewModel>();
            }
        }

        public ReportDataViewModel ReportData
        {
            get
            {
                return ServiceLocator.Current.GetInstance<ReportDataViewModel>();
            }
        }

        public ActualDataViewModel ActualData
        {
            get
            {
                return ServiceLocator.Current.GetInstance<ActualDataViewModel>();
            }
        }


        public IndexViewModel Index
        {
            get
            {
                return ServiceLocator.Current.GetInstance<IndexViewModel>();
            }
        }


        public static void Cleanup()
        {
            // TODO Clear the ViewModels
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DAL;

namespace ShenhuaSQLite
{
    public class InsertDataSQLite
    {
        System.Timers.Timer t;

        int count = 0;

        public InsertDataSQLite(int Interval)
        {
            t = new System.Timers.Timer(Interval);
            t.Elapsed += T_Elapsed;
            t.AutoReset = true;
            t.Enabled = true;
            t.Start();
            count = CommonMethods.CacheCount; //默认为600
        }

        private void T_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (CommonMethods.TCPisConnected)
            {
                InsertActualData();
                if (DateTime.Now.Minute == 0 && DateTime.Now.Second == 0)//整点插入
                {
                    InsertDataHourReport();
                }
            }
        }
        #region 插入实时数据

        
        private void InsertActualData()
        {
            if (CommonMethods.CurrentValue != null && CommonMethods.CurrentValue.Count > 0)
            {
                List<ActualData> actualDataArray = new List<ActualData>();
                
                List<Cache> cache = new List<Cache>();
                FileVarModbusList归档变量集合 在commonMethos里创建的静态变量, 归档, 意味着存入数据库
                //归档信息在json里面存储

                foreach (Variable_Modbus item in CommonMethods.FileVarModbusList)//FileVarModbusList归档集合
                {
                    string varName = item.VarName;//modbus 点表中的名称
                    string remark = item.Note; //注释
                    double value = 0.0;
                    if (!CommonMethods.CurrentValue.ContainsKey(varName) || CommonMethods.CurrentValue[varName].Length == 0)
                    {
                        value = 0.0;

                    }
                    else
                    {
                        value = Convert.ToDouble(CommonMethods.CurrentValue[varName]);
                    }
                    DateTime dt = DateTime.Now;
                    actualDataArray.Add(new ActualData()
                    {
                        InsertTime = dt,
                        VarName = varName,
                        Value = Convert.ToString(value),
                        Remark = remark
                    });

                    cache.Add(new Cache()
                    {
                        InsertTime = dt,
                        VarName = varName,
                        Value = value.ToString(),
                        Remark = remark
                    });
                }

                var count = new ActualDataProvider().Insert(actualDataArray); //向数据库插入数据

                if (CommonMethods.CacheList.Count <= count)//如果Count小于600
                {
                    CommonMethods.CacheList.Add(cache);//集合的集合
                }
                else
                {
                    CommonMethods.CacheList.RemoveAt(0);//把第一个去掉
                    CommonMethods.CacheList.Add(cache);//继续添加
                }


            }
        }
        #endregion

        #region 插入小时数据
        private void InsertDataHourReport()
        {
            List<string> array = new List<string>();
            foreach (Variable_Modbus item in CommonMethods.ReportVarModbusList)
            {
                double value = 0.0;
                if (CommonMethods.CurrentValue.ContainsKey(item.VarName))
                {
                    string Res = CommonMethods.CurrentValue[item.VarName];//键值对,a[key]为值,存了19个变量的值
                    if (Res.Length == 0)
                    {
                        value = 0.0;

                    }
                    else
                    {
                        value = Convert.ToDouble(Res);
                    }
                    array.Add(value.ToString("f1"));
                }

                ReportData reportData = new ReportData()
                {
                    J0GCB11CF101 = array[0],
                    J0GCB12CF101 = array[1],
                    J0GCB13CF101 = array[2],
                    J0GCB20CT101 = array[3],
                    J0GCB20CQ101_NTU = array[4],
                    J0GCB10CP102 = array[5],
                    J0GCB21CF101 = array[6],
                    J0GCB21CF102 = array[7],
                    J0GCB21CP101 = array[8],
                    J0GCB21CP102 = array[9],
                    J0GCB21CQ101_NTU = array[10],
                    J0GCB22CF101 = array[11],
                    J0GCB22CF102 = array[12],
                    J0GCB22CP101 = array[13],
                    J0GCB22CP102 = array[14],
                    J0GCB22CQ101_NTU = array[15],
                    J0GCB31CL101 = array[16],
                    J0GCB32CL101 = array[17],
                    J0GCB50CP101 = array[18]
                };

                var conut = new ReportDataProvider().Insert(reportData);
            }
        }
        #endregion
    }
}

using DAL;
using MahApps.Metro.Controls;
using ShenhuaSQLite.View;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
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;

namespace ShenhuaSQLite
{
    /// 
    /// MainWindow.xaml 的交互逻辑
    /// 
    public partial class MainWindow : MetroWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            AppData.Instance.MainWindow = this;//ApData 中的MainWindow引入
            AppData.Instance.MainWindow.container.Content = new IndexView();
            InitialTxt();
            IniTaskModbus();

        }





        #region 读取配置文件信息


        //定义根目录路径
        private static string FilePath = System.IO.Directory.GetCurrentDirectory() + "\\ConfigFile\\";
        //读取配置文件路径,ini要是ANSI格式
        SettingManager IniManager = new SettingManager(FilePath + "MODBUSTCP_.ini");

        private CancellationTokenSource cts = new CancellationTokenSource();

        //插入数据库
        InsertDataSQLite objInsert = new InsertDataSQLite(10000);//10秒1次

        #endregion

        #region Socket 操作

        private bool OpenTCP(ModbusTCPEntity modbusTCP)
        {
            return CommonMethods.objModTCP.Connect(modbusTCP.Ip, modbusTCP.Port);
        }

        private bool CloseTCP(ModbusTCPEntity modbusTCP)
        {
            return CommonMethods.objModTCP.Disconnect();
        }

        #endregion

        #region 初始化信息
        private void InitialTxt()
        {
            //第一步: 加载通讯接口信息
            CommonMethods.objModbusTCPEntity = IniManager.LoadSysSettings();

            //第二步: 变量集合信息
            CommonMethods.VarModbusList = CommonMethods.LoadJsonVarible(FilePath + "Variable_Modbus.json");
            CommonMethods.StoreAreaList = CommonMethods.LoadJsonStoreType(FilePath + "StoreArea.json");

            //第三步: 其他初始化 实时接收值, 将配置信息写入CurrentValue与CurrentVarAddress
            foreach (Variable_Modbus item in CommonMethods.VarModbusList)
            {
                if (!CommonMethods.CurrentValue.ContainsKey(item.VarName)) 变量名和数值的字典集合
                {
                    CommonMethods.CurrentValue.Add(item.VarName, "");
                    CommonMethods.CurrentVarAddress.Add(item.VarName, item.Address);
                }

                if (item.StoreArea == "01 Coil Status(0x)")
                {
                    CommonMethods.List_0x.Add(item); //CommThread objComm = new CommThread(); CommThread中的方法
                }

                if (item.StoreArea == "02 Input Status(1x)")
                {
                    CommonMethods.List_1x.Add(item);
                }

                if (item.StoreArea == "03 Holding Register(4x)")
                {
                    CommonMethods.List_4x.Add(item);
                }

                if (item.StoreArea == "04 Input Register(3x)")
                {
                    CommonMethods.List_3x.Add(item); //存储实时数据
                }

                if (item.IsFiling == "1")//是否归档
                {
                    CommonMethods.FileVarModbusList.Add(item);
                    CommonMethods.CurrentVarNote.Add(item.VarName, item.Note);
                    CommonMethods.FileVarNameList.Add(item.Note);
                }
                if (item.IsReport == "1")//是否做报表
                {
                    CommonMethods.ReportVarModbusList.Add(item);
                }
            }

        }
        #endregion

        #region 打开线程读取数据

        private void IniTaskModbus()
        {
            

            bool a;
            Task.Run(async () =>
            {
                await Task.Delay(200);

                OpenTCP(CommonMethods.objModbusTCPEntity);//是否运行?
                
                await Task.Delay(200);
                CommonMethods.TCPisConnected = true;
                while (!cts.IsCancellationRequested)
                {
                    await Task.Delay(1000);
                    if (CommonMethods.TCPisConnected)
                    {
                        CommonMethods.treadTCP.Communication();
                        //this.ErrorTimer <= this.MaxErrorTimer
                        if (CommonMethods.treadTCP.ErrorTimer > 0 & CommonMethods.treadTCP.ErrorTimer <= CommonMethods.treadTCP.MaxErrorTimer)
                        {
                            await Task.Delay(3000);
                            CommonMethods.treadTCP.Communication();
                            CommonMethods.treadTCP.FirstConnect = false;
                        }
                        else if (!CommonMethods.treadTCP.IsConnected)//this.ErrorTimer >= this.MaxErrorTimer
                        {
                            CommonMethods.TCPisConnected = false;
                        }
                    }
                    else
                    {
                        if (!CommonMethods.treadTCP.FirstConnect)
                        {
                            await Task.Delay(3000);
                            CommonMethods.objModTCP?.Disconnect();
                        }

                        OpenTCP(CommonMethods.objModbusTCPEntity);
                        CommonMethods.treadTCP = new TreadTCP();
                        CommonMethods.TCPisConnected = true;
                        CommonMethods.treadTCP.FirstConnect = false;
                    }

                }
                //else
                //{
                //    CommonMethods.TCPisConnected = false;
                //}
            }, cts.Token);


        }
        #endregion
    }
}
using DAL;
using LiveCharts;
using LiveCharts.Wpf;
using ShenhuaSQLite.ViewModel;
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;

namespace ShenhuaSQLite.View
{
    /// 
    /// IndexView.xaml 的交互逻辑
    /// 
    public partial class IndexView : UserControl
    {
        public IndexView()
        {
            InitializeComponent();
            Loaded += (s, e) =>
            {
                Task.Run(() =>
                {
                    var vm = DataContext as IndexViewModel;
                    var actualDataProvider = new ActualDataProvider();
                    var actuals = actualDataProvider.Select();
                    vm.AcualLabels.Clear();
                    vm.ActualChartValues.Clear();


                    using (MainEntities context = new MainEntities())
                    {
                        var actualData1 = context.ActualData.Where(u => u.Remark == "2号超滤装置进口压力").ToList();
                        var serise = new LineSeries();
                        //serise.Title = actualData1;
                        serise.Values = new ChartValues<double>();
                        Axis axis = new Axis();
                        axis.ShowLabels = true;
                        axis.Labels = new List<string>();
                        actualData1.ForEach(u =>
                        {
                            axis.Labels.Add(u.InsertTime.ToString());
                            serise.Values.Add(Convert.ToDouble(u.Value));
                        });
                        vm.LineSeries.Add(serise);
                        vm.LineAxis.Add(axis);
                    }



                });
            };
        }

        /*
                 
            
                
                
            
            
                
                
            

            
        
         
         */
    }
}

<UserControl
    x:Class="ShenhuaSQLite.View.ActualDataView"
    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:local="clr-namespace:ShenhuaSQLite.View"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
    d:DesignHeight="450"
    d:DesignWidth="800"
    Background="{StaticResource AppBackground}"
    DataContext="{Binding Source={StaticResource Locator},Path=ActualData}"
    mc:Ignorable="d">
    <Grid>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="70"/>
                <RowDefinition/>
            Grid.RowDefinitions>
            <Border BorderBrush="Black" BorderThickness="0,0,0,1">
                <TextBlock
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    FontSize="24"
                    Foreground="White"
                    Text="实时数据" />
            Border>

            
            <TextBlock
                Margin="0,0,25,0"
                HorizontalAlignment="Right"
                VerticalAlignment="Center"
                FontFamily="../Font/#FontAwesome"
                Text="">
                <TextBlock.Style>
                    <Style TargetType="TextBlock">
                        
                        
                            "IsMouseOver" Value="True">
                                "FontSize" Value="28" />
                                "Cursor" Value="Hand" />
                                "Foreground" Value="Green" />
                            
                            "IsMouseOver" Value="False">
                                "FontSize" Value="24" />
                                "Foreground" Value="White" />
                            
                        
                    Style>
                TextBlock.Style>
                
                <b:Interaction.Triggers>
                    <b:EventTrigger EventName="MouseUp">
                        <b:InvokeCommandAction Command="{Binding OpenAddActulDataWindowCommand}" />
                    b:EventTrigger>
                b:Interaction.Triggers>

            TextBlock>

            <Grid Grid.Row="1">
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition Height="60" />
                Grid.RowDefinitions>
                
                <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding ActualDatas}">
                    <DataGrid.Columns>
                        <DataGridTextColumn Binding="{Binding Id}" Header="编号" />
                        <DataGridTextColumn Binding="{Binding VarName}" Header="变量名" />
                        <DataGridTextColumn Binding="{Binding Value}" Header="实时数值" />
                        <DataGridTextColumn Binding="{Binding Remark}" Header="中文名" />
                        <DataGridTextColumn Binding="{Binding InsertTime}" Header="插入日期" />

                        <DataGridTemplateColumn Header="操作">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock HorizontalAlignment="Center" Text="删除">
                                        <TextBlock.Style>
                                            <Style TargetType="TextBlock">
                                                
                                                    "IsMouseOver" Value="True">
                                                        "Foreground" Value="Red" />
                                                        "Cursor" Value="Hand" />
                                                    
                                                
                                            Style>
                                        TextBlock.Style>
                                        <b:Interaction.Triggers>
                                            <b:EventTrigger EventName="MouseUp">
                                                <b:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:ActualDataView}, Path=DataContext.DeleteActualDataCommand}" CommandParameter="{Binding}" />
                                            b:EventTrigger>
                                        b:Interaction.Triggers>
                                    TextBlock>
                                DataTemplate>
                            DataGridTemplateColumn.CellTemplate>
                        DataGridTemplateColumn>
                    DataGrid.Columns>
                DataGrid>

                <StackPanel
                    Grid.Row="1"
                    Margin="5"
                    Orientation="Horizontal">
                    <TextBlock
                        FontSize="16"
                        Foreground="White"
                        Text="统计:" />
                    <TextBlock
                        FontSize="16"
                        Foreground="White"
                        Text="{Binding Actualcount.Count}" />
                StackPanel>
            Grid>

        Grid>
    Grid>
UserControl>

<mah:MetroWindow
    x:Class="ShenhuaSQLite.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:i="http://schemas.microsoft.com/xaml/behaviors"
    xmlns:local="clr-namespace:ShenhuaSQLite"
    xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="{Binding appData.SystemName}"
    Width="1200"
    Height="700"
    Background="#2B2C31"
    DataContext="{Binding Source={StaticResource Locator}, Path=Main}"
    WindowStartupLocation="CenterScreen"
    WindowState="Maximized"
    mc:Ignorable="d">
    <mah:MetroWindow.Resources>
        <Storyboard x:Key="OnChecked1">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="leftBorder" Storyboard.TargetProperty="(FrameworkElement.Width)">
                <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="45" />
            DoubleAnimationUsingKeyFrames>
        Storyboard>
        <Storyboard x:Key="OnUnchecked1">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="leftBorder" Storyboard.TargetProperty="(FrameworkElement.Width)">
                <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="200" />
            DoubleAnimationUsingKeyFrames>
        Storyboard>
    mah:MetroWindow.Resources>
    <mah:MetroWindow.Triggers>
        <EventTrigger RoutedEvent="ToggleButton.Checked" SourceName="toggleButton">
            <BeginStoryboard Storyboard="{StaticResource OnChecked1}" />
        EventTrigger>
        <EventTrigger RoutedEvent="ToggleButton.Unchecked" SourceName="toggleButton">
            <BeginStoryboard Storyboard="{StaticResource OnUnchecked1}" />
        EventTrigger>
    mah:MetroWindow.Triggers>


    <Grid>
        
        <Grid
            x:Name="markLayer"
            Panel.ZIndex="999"
            Background="Black"
            Opacity="0.8"
            Visibility="Hidden" />
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="auto" />
                <ColumnDefinition />
            Grid.ColumnDefinitions>
            
            <Border
                x:Name="leftBorder"
                Width="200"
                Background="#2B2C31"
                BorderThickness="0,0,1,0">
                <Border.Effect>
                    <DropShadowEffect
                        BlurRadius="10"
                        Opacity="0.5"
                        ShadowDepth="0"
                        Color="Black" />
                Border.Effect>


                <Grid Grid.Column="0">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="auto" />
                        <RowDefinition />
                    Grid.RowDefinitions>
                    <StackPanel Margin="0,15,0,15" Orientation="Horizontal">
                        <StackPanel.Effect>
                            <DropShadowEffect
                                BlurRadius="10"
                                Opacity="0.5"
                                ShadowDepth="0"
                                Color="Black" />
                        StackPanel.Effect>
                        <TextBlock
                            Margin="10"
                            FontFamily="Font/#FontAwesome"
                            FontSize="30"
                            Foreground="#297790"
                            Text="" />
                        <TextBlock
                            VerticalAlignment="Center"
                            FontFamily="Font/#FontAwesome"
                            FontSize="20"
                            Foreground="White"
                            Text="{Binding appData.SystemName}" />
                    StackPanel>
                    <StackPanel Grid.Row="1">
                        <RadioButton
                            Width="200"
                            Height="50"
                            Content="首页"
                            FontSize="18"
                            Foreground="White"
                            Style="{DynamicResource RadioButtonMenuStyle}"
                            Tag="">
                            
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="Checked">
                                    <i:InvokeCommandAction Command="{Binding SelectViewCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=RadioButton}}" />
                                i:EventTrigger>
                            i:Interaction.Triggers>
                        RadioButton>


                        <RadioButton
                            Width="200"
                            Height="50"
                            Content="控制流程"
                            FontSize="18"
                            Foreground="White"
                            Style="{DynamicResource RadioButtonMenuStyle}"
                            Tag="">
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="Checked">
                                    <i:InvokeCommandAction Command="{Binding SelectViewCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=RadioButton}}" />
                                i:EventTrigger>
                            i:Interaction.Triggers>
                        RadioButton>

                        <RadioButton
                            Width="200"
                            Height="50"
                            Content="硬件组态"
                            FontSize="18"
                            Foreground="White"
                            Style="{DynamicResource RadioButtonMenuStyle}"
                            Tag="">
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="Checked">
                                    <i:InvokeCommandAction Command="{Binding SelectViewCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=RadioButton}}" />
                                i:EventTrigger>
                            i:Interaction.Triggers>
                        RadioButton>

                        <RadioButton
                            Width="200"
                            Height="50"
                            Content="历史趋势"
                            FontSize="18"
                            Foreground="White"
                            Style="{DynamicResource RadioButtonMenuStyle}"
                            Tag="">
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="Checked">
                                    <i:InvokeCommandAction Command="{Binding SelectViewCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=RadioButton}}" />
                                i:EventTrigger>
                            i:Interaction.Triggers>
                        RadioButton>

                        <RadioButton
                            Width="200"
                            Height="50"
                            Content="数据报表"
                            FontSize="18"
                            Foreground="White"
                            Style="{DynamicResource RadioButtonMenuStyle}"
                            Tag="">
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="Checked">
                                    <i:InvokeCommandAction Command="{Binding SelectViewCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=RadioButton}}" />
                                i:EventTrigger>
                            i:Interaction.Triggers>
                        RadioButton>


                        <RadioButton
                            Width="200"
                            Height="50"
                            Content="参数设置"
                            FontSize="18"
                            Foreground="White"
                            Style="{DynamicResource RadioButtonMenuStyle}"
                            Tag="">
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="Checked">
                                    <i:InvokeCommandAction Command="{Binding SelectViewCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=RadioButton}}" />
                                i:EventTrigger>
                            i:Interaction.Triggers>
                        RadioButton>
                    StackPanel>
                Grid>
            Border>
            
            <Grid Grid.Column="1">
                <ToggleButton
                    x:Name="toggleButton"
                    Width="30"
                    Height="30"
                    Margin="10,20"
                    HorizontalAlignment="Left"
                    VerticalAlignment="Top"
                    Panel.ZIndex="99"
                    Content=""
                    FontFamily="Font/#FontAwesome"
                    FontSize="20"
                    Foreground="White"
                    Style="{DynamicResource ToggleButtonStyle}" />
                <ContentControl x:Name="container" />
            Grid>

        Grid>
    Grid>
mah:MetroWindow>

<mah:MetroWindow
    x:Class="ShenhuaSQLite.Windows.LoginWindow"
    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:i="http://schemas.microsoft.com/xaml/behaviors"
    xmlns:local="clr-namespace:ShenhuaSQLite.Windows"
    xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="LoginWindow"
    Width="600"
    Height="350"
    DataContext="{Binding Source={StaticResource Locator}, Path=Login}"
    ResizeMode="NoResize"
    WindowStartupLocation="CenterScreen"
    mc:Ignorable="d">
    <Grid>
        <Grid Margin="100,50,100,50">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            Grid.RowDefinitions>
            <TextBlock
                HorizontalAlignment="Center"
                FontSize="36"
                Text="焦作神华补水预处理系统" />
            <StackPanel
                Grid.Row="1"
                Margin="10,0,0,0"
                VerticalAlignment="Center"
                Orientation="Horizontal">
                <TextBlock
                    Width="60"
                    Margin="50,0,0,0"
                    FontSize="18"
                    Text="用户名" />
                <TextBox
                    Width="200"
                    Margin="10,0,0,0"
                    Text="{Binding appData.CurrentUser.LoginName}" />
            StackPanel>
            <StackPanel
                Grid.Row="2"
                Margin="10,0,0,0"
                VerticalAlignment="Center"
                Orientation="Horizontal">
                <TextBlock
                    Width="60"
                    Margin="50,0,0,0"
                    FontSize="18"
                    Text="密码" />

                <TextBox
                    Width="200"
                    Margin="10,0,0,0"
                    Text="{Binding appData.CurrentUser.LoginPwd}" Background="Transparent">
                    <TextBox.Style>
                        <Style TargetType="{x:Type TextBox}">
                            "TextDecorations">
                                
                                    
                                        
                                            
                                                "Black"
                                                    DashCap="Round"
                                                    EndLineCap="Round"
                                                    StartLineCap="Round"
                                                    Thickness="10">
                                                    
                                                        "0.0,1.2" Offset="0.6" />
                                                    
                                                
                                            
                                            
                                                Strikethrough
                                            
                                        
                                    
                                

                            
                            "Height" Value="30" />
                            "Background" Value="#FF484D5E" />
                            "Foreground" Value="Transparent" />
                            "FontSize" Value="20" />
                            "FontFamily" Value="Courier New" />
                        Style>
                    TextBox.Style>
                TextBox>

            StackPanel>
            <StackPanel
                Grid.Row="3"
                Margin="65,0,0,0"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Orientation="Horizontal">
                <Button
                    Width="80"
                    Command="{Binding LoginCommand2}"
                    CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
                    Content="登录" />
                <Button
                    Width="80"
                    Margin="40,0,0,0"
                    Command="{Binding CloseCommand}"
                    Content="取消" />
            StackPanel>
        Grid>
    Grid>
mah:MetroWindow>

你可能感兴趣的:(wpf,c#,单例模式)