1. 程式人生 > 實用技巧 >WPF基於.Net Core

WPF基於.Net Core

WPF基於.Net Core

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

  • 使用VS2019作為開發工具

  • 實現MVVM模式

1、實現基礎專案

使用VS2019新建WPF App專案

![image-20200710193416617](C:\Users\fangzhongwei\Desktop\WPF Net Core\image\image-20200710193416617.png)

專案名稱Common

1.1、修改專案屬性

  • 刪除專案MainWindow.xaml以及MainWindow.xaml.cs檔案

  • 刪除App.xaml和App.xaml.cs檔案

  • 修改專案輸出為類庫

    ![image-20200710193806136](C:\Users\fangzhongwei\Desktop\WPF Net Core\image\image-20200710193806136.png)

  • 新增Command資料夾

    ![image-20200710193823822](C:\Users\fangzhongwei\Desktop\WPF Net Core\image\image-20200710193823822.png)

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三個資料夾

![image-20200711130227939](C:\Users\fangzhongwei\Desktop\WPF Net Core\image\image-20200711130227939.png)

刪除MainWindow.xaml

![image-20200711130756699](C:\Users\fangzhongwei\Desktop\WPF Net Core\image\image-20200711130756699.png)

2.2、新增窗體MainView.xaml

![image-20200711131905603](C:\Users\fangzhongwei\Desktop\WPF Net Core\image\image-20200711131905603.png)

修改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檔案

![image-20200711133707892](C:\Users\fangzhongwei\Desktop\WPF Net Core\image\image-20200711133707892.png)

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,新增啟動事件以及異常捕捉事件

![image-20200711131032509](C:\Users\fangzhongwei\Desktop\WPF Net Core\image\image-20200711131032509.png)

<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的分離

![image-20200711134557199](C:\Users\fangzhongwei\Desktop\WPF Net Core\image\image-20200711134557199.png)