WPF基於.Net Core


WPF基於.Net Core

因為最近.net core的熱門,所以想實現一下.net core框架下的WPF項目,還是MVVM模式,下面就開始吧,簡單做一個計算器吧。

  • 使用VS2019作為開發工具

  • 實現MVVM模式

1、實現基礎項目

使用VS2019新建WPF App項目

項目名稱Common

1.1、修改項目屬性

  • 刪除項目MainWindow.xaml以及MainWindow.xaml.cs文件

  • 刪除App.xaml和App.xaml.cs文件

  • 修改項目輸出為類庫

  • 添加Command文件夾

2.2、實現ICommand接口

定義BaseCommand類實現ICommand接口

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Input;

namespace Common.Command
{
    /// <summary>
    /// 實現ICommand接口
    /// </summary>
    public class BaseCommand : ICommand
    {
        public Predicate<object> CanExecuteDelegate { get; set; }
        public Action<object> ExecuteDelegate { get; set; }

        public BaseCommand(Action<object> execute)
        {
            ExecuteDelegate = execute;
        }

        public BaseCommand(Action<object> execute, Predicate<object> canExecute)
        {
            CanExecuteDelegate = canExecute;
            ExecuteDelegate = execute;
        }

        public BaseCommand()
        {
        }

        /// <summary>
        /// Defines the method that determines whether the command can execute in its current state.
        /// </summary>
        public bool CanExecute(object parameter)
        {
            if (CanExecuteDelegate != null)
                return CanExecuteDelegate(parameter);
            return true;
        }

        /// <summary>
        /// Occurs when changes occur that affect whether the command should execute.
        /// </summary>
        public event EventHandler CanExecuteChanged
        {
            add
            {
                CommandManager.RequerySuggested += value;
            }

            remove
            {
                CommandManager.RequerySuggested -= value;
            }
        }

        /// <summary>
        /// 執行
        /// </summary>
        public void Execute(object parameter)
        {
            try
            {
                if (ExecuteDelegate != null)
                    ExecuteDelegate(parameter);
            }
            catch (Exception ex)
            {
                string moudle = ExecuteDelegate.Method.DeclaringType.Name + ":" + ExecuteDelegate.Method.Name;
            }
        }

        /// <summary>
        /// Raises the CanExecuteChanged event.
        /// </summary>
        public void InvalidateCanExecute()
        {
            CommandManager.InvalidateRequerySuggested();
        }
    }
}

2.3、實現INotifyPropertyChanged接口

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;

namespace Common.Command
{
    /// <summary>
    /// 實現INotifyPropertyChanged接口
    /// </summary>
    public class NotifyPropertyBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;


        public void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public object Clone()
        {
            return this.MemberwiseClone();
        }
    }
}

2、主程序HelloCore

2.1、新建WPF APP項目

項目名稱為HelloCore

新建View、ViewModel、Model三個文件夾

刪除MainWindow.xaml

2.2、添加窗體MainView.xaml

修改MainView.xaml

<Window x:Class="HelloCore.View.MainView"
        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:HelloCore.View"
        mc:Ignorable="d"
        Title="HelloCore" Height="350" Width="600">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <TextBox Text="{Binding Result}" Margin="5"/>
        <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
            <Button Content="HelloCore" Command="{Binding HelloCommand}" Margin="10" Width="80" Height="30"/>
            <Button Content="Clear" Command="{Binding ClearCommand}" Margin="10" Width="80" Height="30"/>
        </StackPanel>
    </Grid>
</Window>

2.3、添加MainViewModel.cs文件

using Common.Command;
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Input;

namespace HelloCore.ViewModel
{
    public class MainViewModel : NotifyPropertyBase
    {
        private string _result;

        /// <summary>
        /// 綁定到界面上TextBox的Text屬性上
        /// </summary>
        public string Result
        {
            get
            {
                return _result;
            }
            set
            {
                _result = value;
                OnPropertyChanged("Result");
            }
        }

        private ICommand _helloCommand;
        private ICommand _clearCommand;

        public ICommand HelloCommand
        {
            get
            {
                return this._helloCommand ?? (this._helloCommand = new BaseCommand()
                {
                    CanExecuteDelegate = x => true,
                    ExecuteDelegate = x =>
                    {
                        Result = "Hello Net Core";
                    }
                });
            }
        }

        public ICommand ClearCommand
        {
            get
            {
                return this._clearCommand ?? (this._clearCommand = new BaseCommand()
                {
                    CanExecuteDelegate = x => true,
                    ExecuteDelegate = x =>
                    {
                        Result = "";
                    }
                });
            }
        }
    }
}

2.4、通過DataContext綁定

在MainView.xaml.cs中添加DataContext進行MainView和MainViewModel的綁定

using HelloCore.ViewModel;
using System.Windows;

namespace HelloCore.View
{
    /// <summary>
    /// MainView.xaml 的交互邏輯
    /// </summary>
    public partial class MainView : Window
    {
        MainViewModel vm = new MainViewModel();
        public MainView()
        {
            InitializeComponent();
            this.DataContext = vm;
        }
    }
}

2.5、修改App.xmal文件

修改App.xaml文件,刪除StartupUri,添加啟動事件以及異常捕捉事件

<Application x:Class="HelloCore.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:HelloCore"
             Startup="Application_Startup"
             DispatcherUnhandledException="Application_DispatcherUnhandledException">
    <Application.Resources>
         
    </Application.Resources>
</Application>

2.6、修改App.xaml.cs文件

using HelloCore.View;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;

namespace HelloCore
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        MainView mainWindow;
        public App()
        {
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionEventHandler);
        }

        private static void UnhandledExceptionEventHandler(object sender, UnhandledExceptionEventArgs e)
        {

        }

        /// <summary>
        /// 重寫Starup函數,程序重這里啟動
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            mainWindow = new MainView();
            mainWindow.Show();
        }

        /// <summary>
        /// 異常處理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            // .Net4.0及之前版本訪問剪切板默寫情況下可能失敗報異常
            // OpenClipboard HRESULT:0x800401D0 (CLIPBRD_E_CANT_OPEN))
            var comException = e.Exception as System.Runtime.InteropServices.COMException;
            if (comException != null && comException.ErrorCode == -2147221040)
            {
                e.Handled = true;
            }

            // 未捕獲的異常
            e.Handled = true;
        }
    }
}

2.7、啟動程序,觀看結果

到這里一個簡單的基於.net core的WPF應用程序就完成啦,當然WPF真正的魅力沒有展示出來,MVVM模式的意義大概是這樣了,實現View和Model的分離


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM