WPF 應用遷移到 Electron 框架過程記錄

来源:https://www.cnblogs.com/he55/p/18046511
-Advertisement-
Play Games

前一段時間我用 WPF 開發了一個查看 emoji 表情的小工具 https://github.com/he55/EmojiViewer ,由於最近我使用 macOS 系統比較多,我想能在 macOS 系統上也能使用這個工具。於是我嘗試將 WPF 應用遷移到 Electron 框架,感覺這個框架很強 ...


前一段時間我用 WPF 開發了一個查看 emoji 表情的小工具 https://github.com/he55/EmojiViewer ,由於最近我使用 macOS 系統比較多,我想能在 macOS 系統上也能使用這個工具。於是我嘗試將 WPF 應用遷移到 Electron 框架,感覺這個框架很強大,在這裡記錄一下應用遷移的過程。

安裝 Electron 環境

  • 安裝 nodejs。到官網 https://nodejs.org/en 下載最新的 nodejs,然後安裝
  • 打開命令行輸入 git clone https://github.com/electron/electron-quick-start.git 命令克隆 Electron 模板項目,使用模板可以快速搭建應用。
  • 然後使用 cd electron-quick-start 目錄進入到目錄,接著運行 npm install 命令還原項目。
  • 使用 vscode 打開文件夾,項目文件如下

編寫代碼

  • Electron 分為主進程和渲染進程,對文件、系統和視窗的操作需要在主線程,界面渲染在渲染進程。創建視窗屬於主進程的工作,需要到 main.js 文件編寫代碼。創建視窗使用 BrowserWindow 對象,widthheight 分別設置視窗寬度和高度,autoHideMenuBar 設置是否隱藏菜單,最後使用 loadFile 載入頁面文件並顯示視窗。
function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 915,
    height: 560,
    autoHideMenuBar: true,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })

  mainWindow.loadFile('index.html')
}
  • 監聽 whenReady 事件,等待應用初始化完成後顯示視窗
app.whenReady().then(() => {
  createWindow()

  app.on('activate', function () {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})
  • 修改 index.html 文件,界面部分使用了 vue 進行渲染
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <script src="vue.global.js"></script>
  <link href="./styles.css" rel="stylesheet">
  <title>EmojiViewer</title>
</head>

<body>
  <div id="app" class="container">
    <ul class="left">
      <li v-for="(item, key) in categories" :class="{active: item.isActive}" @click="catetoryItemClick(item)">{{ key }}</li>
    </ul>
    <ul class="main" ref="mainElement">
      <li v-for="emoji in emojis" :class="{active: emoji.isActive}" @click="emojiItemClick(emoji)">
        <img :src="emoji.previewImage" alt="">
        <p>{{emoji.name}}</p>
      </li>
    </ul>
    <div class="right">
      <img :src="selectedEmoji.previewImage">
      <p>{{ selectedEmoji.name }}</p>
      <button @click="copyEmoji(selectedEmoji)" type="button">Copy Emoji</button>
      <button @click="copyImage(selectedEmoji)" type="button">Copy Image</button>
      <button @click="openFile(selectedEmoji)" type="button">Open File</button>
    </div>
  </div>

  <script src="./renderer.js"></script>
</body>

</html>
  • renderer.js 文件中編寫頁面處理代碼
window.addEventListener('DOMContentLoaded', async () => {
    const { createApp, ref, onMounted } = Vue
    let emojiData = await ipc.getData()

    createApp({
        setup() {
            const mainElement = ref(null)

            const categories = ref(emojiData)
            const emojis = ref([])
            const selectedEmoji = ref({})

            function copyEmoji(emoji) {
                ipc.ipc('writeText', emoji.metadata.glyph)
            }
            function copyImage(emoji) {
                ipc.ipc('writeImage', emoji.previewImage)
            }
            function openFile(emoji) {
                ipc.ipc('showItemInFolder', emoji.previewImage)
            }

            let lastSelectedEmojis
            function catetoryItemClick(items) {
                if (lastSelectedEmojis) {
                    lastSelectedEmojis.isActive = false
                }

                items.isActive = true
                lastSelectedEmojis = items

                // const main = document.querySelector('.main')
                mainElement.value.scrollTop = 0
                emojis.value = items
            }

            function emojiItemClick(emoji) {
                if (selectedEmoji.value) {
                    selectedEmoji.value.isActive = false
                }

                emoji.isActive = true
                selectedEmoji.value = emoji
            }

            onMounted(() => {
                catetoryItemClick(emojiData['Activities'])
                emojiItemClick(emojiData['Activities'][0])
            })

            return {
                mainElement,
                categories,
                emojis,
                selectedEmoji,
                catetoryItemClick,
                emojiItemClick,
                copyEmoji,
                copyImage,
                openFile,
            }
        }
    }).mount('#app')
})
  • 讀取文件,node 提供了文件操作相關的 api 可以很方便的操作文件系統。
function loadData(assetPath) {
  const dirs = fs.readdirSync(assetPath)
  const data = []
  const groupData = {}
  for (const dir of dirs) {
    const fullPath = path.resolve(assetPath, dir)
    const metadata = require(path.resolve(fullPath, 'metadata.json'))
    let previewImage

    let imagePaths = [path.resolve(fullPath, '3D'), path.resolve(fullPath, 'Default', '3D')]
    for (const imagePath of imagePaths) {
      if (fs.existsSync(imagePath)) {
        let files = fs.readdirSync(imagePath)
        if (files.length === 0)
          return
        previewImage = path.resolve(imagePath, files[0])
      }
    }

    const { unicode, group } = metadata
    const obj = {
      metadata,
      id: unicode,
      name: dir,
      previewImage,
    }
    data.push(obj)

    if (!groupData[group])
      groupData[group] = []
    groupData[group].push(obj)
  }
  return groupData
}

完整代碼(WPF 版本) https://github.com/he55/EmojiViewer
完整代碼(vue 版本) https://github.com/he55/web-learn/tree/main/9.electron-emoji-viewer(vue)
完整代碼(js 原生版本) https://github.com/he55/web-learn/tree/main/6.electron-emoji-viewer


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • CYQ.Data 是一個用於操作資料庫的框架,可以方便地連接和管理各種類型的資料庫。在操作達夢資料庫時,使用 CYQ.Data 框架可以提供以下功能和優勢......總的來說,使用 CYQ.Data 框架操作達夢資料庫可以簡化開發流程,提高開發效率,同時也增強了系統的穩定性和安全性。 ...
  • 一:背景 1. 講故事 先說一下題外話,一個監控別人系統運行狀態的程式,結果自己出問題了,有時候想一想還是挺諷刺的,哈哈,開個玩笑,我們回到正題,前些天有位朋友找到我,說他們的系統會偶發性CPU爆高,CPU上去了就下不來了,讓我幫忙看一下怎麼回事,而且自己也分析過了,沒找到哪裡有問題,寫監控的都是高 ...
  • Playwright 是一個由 Microsoft 開發的開源工具,用於自動化 Web 瀏覽器的測試和操作。它提供了一種跨瀏覽器、跨平臺的自動化解決方案,可以在 Chromium、Firefox 和 WebKit(Safari)等多種瀏覽器上進行測試和操作。本篇隨筆介紹Playwright的一些特點... ...
  • 概述:在.NET Core中,通過創建RequestCountMiddleware中間件,結合MemoryCache,實現了記錄最近5分鐘請求次數的功能。該中間件在每個請求中更新計數,並使用緩存存儲,為簡單而實用的請求監控提供了一個示例。 要實現一個在.NET Core中記錄最近5分鐘請求次數的Re ...
  • 人大金倉優點 人大金倉是國產最主流資料庫之一 具有和PgSql一樣強悍的性能,同時人大金倉支持了四種資料庫模式 : Oracle、PgSql、MySql和SqlServer ,假如你們系統有多種資料庫開發 有國產化要求,那麼你們切換到人大金倉就會很方便了 Nuget安裝 C# ORM 搜索人大金倉安 ...
  • 介紹FastWiki FastWiki是一個高性能、基於最新技術棧的知識庫系統,旨在為大規模信息檢索和智能搜索提供解決方案。它採用微軟Semantic Kernel進行深度學習和自然語言處理,在後端使用MasaFramework,前端採用MasaBlazor框架,實現了一個高效、易用、可擴展的智能向 ...
  • 通過引入分散式冪等性框架,可以有效處理分散式系統中的重覆操作問題,確保系統穩定運行並保持數據的一致性。 ...
  • 前言 雖然已經正式轉JAVA了,但最近發現一個特別好的開源項目masuit,不僅提供很多簡便的功能,還有圖像的一些特殊操作功能。 之前我們比較圖片應該都是使用的openCV,不過這個masuit,看上去也不錯,而且代碼使用簡單,因此強烈推薦。 下麵就實現一個簡單圖像對比。 實現對比 首先添加引用ma ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...