C# WINDOWS MAUI專案 建立自訂彈出對話合視窗(Custom PopupPage/Dialog)
C# WINDOWS MAUI專案 建立自訂彈出對話合視窗(Custom PopupPage/Dialog)
資料來源: https://www.youtube.com/watch?v=yM7opXlu-MU [Showing Popups in .NET MAUI with .NET MAUI Community Toolkit]
GITHUB:
https://github.com/jash-git/MAUI_WinAPI_Object_test/tree/main/Code/04
https://github.com/jash-git/MAUI_WinAPI_Object_test/tree/main/Code/13 [指定顯示在0,0位置 ~ (HorizontalOptions=”Start” VerticalOptions=”Start”)]
PopupPage.xaml Code:
<?xml version="1.0" encoding="utf-8" ?> <mct:Popup xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:mct="clr-namespace:CommunityToolkit.Maui.Views;assembly=CommunityToolkit.Maui" x:Class="MAUI_WinAPI_Object_test.PopupPage" CanBeDismissedByTappingOutsideOfPopup="False"> <VerticalStackLayout BackgroundColor="Blue"> <Label Text="Welcome to .NET MAUI!" VerticalOptions="Center" HorizontalOptions="Center" /> <Button x:Name="CloseBtn" Text="Close App" Clicked="OnClosed" HorizontalOptions="Center" ClassId="" /> </VerticalStackLayout> </mct:Popup>
PopupPage.xaml.cs Code:
using CommunityToolkit.Maui.Views; namespace MAUI_WinAPI_Object_test; public partial class PopupPage: Popup // : ContentPage { public PopupPage() { InitializeComponent(); //Size = new Size(500, 500);//設定UI大小 } private void OnClosed(object sender, EventArgs e) { Close(); } }
MainPage.xaml Code:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="MAUI_WinAPI_Object_test.MainPage"> <ScrollView> <VerticalStackLayout Spacing="25" Padding="30,0" VerticalOptions="Center"> <Image Source="dotnet_bot.png" SemanticProperties.Description="Cute dot net bot waving hi to you!" HeightRequest="200" HorizontalOptions="Center" /> <Label x:Name="labtime" Text="Hello, World!" SemanticProperties.HeadingLevel="Level1" FontSize="32" HorizontalOptions="Center" /> <Label Text="Welcome to .NET Multi-platform App UI" SemanticProperties.HeadingLevel="Level2" SemanticProperties.Description="Welcome to dot net Multi platform App U I" FontSize="18" HorizontalOptions="Center" /> <Button x:Name="CounterBtn" Text="Click me" SemanticProperties.Hint="Counts the number of times you click" Clicked="OnCounterClicked" HorizontalOptions="Center" /> <Button x:Name="PopupBtn" Text="Show Popup" SemanticProperties.Hint="Counts the number of times you click" Clicked="OnPopupClicked" HorizontalOptions="Center" /> <Button x:Name="CloseBtn" Text="Close App" Clicked="OnClosed" HorizontalOptions="Center" ClassId="" /> </VerticalStackLayout> </ScrollView> </ContentPage>
MainPage.xaml.cs Code
//using Android.App; using CommunityToolkit.Maui.Views; using Jint; using Microsoft.Maui.Controls; using System.Data; using System.Data.SQLite; using System.IO.Ports; using System.Text; using System.Text.Json; using System.Threading.Tasks; namespace MAUI_WinAPI_Object_test; public partial class MainPage : ContentPage { int count = 0; public IDispatcherTimer timmer { get; set; } public Thread thread; public bool blnStop = false; public MainPage() { InitializeComponent(); /* //--- //Timer Mode //https://learn.microsoft.com/en-us/answers/questions/1207012/how-to-stop-device-starttimer timmer = Application.Current.Dispatcher.CreateTimer(); timmer.Interval = new TimeSpan(0, 0, 0, 0, 100);//天/時/分/秒/毫秒 timmer.Tick += Timmer_Tick; timmer.IsRepeating = true;//the timer will keep recurring, you can set false timmer.Start(); //---Timer Mode //*/ // 在新執行緒中執行工作 thread = new Thread(ThreadFun); thread.Start(); } private void Timmer_Tick(object sender, EventArgs e) { labtime.Text = DateTime.Now.ToString("HH:mm:ss"); } private void ThreadFun() { // 模擬一些耗時的工作 do { // 更新使用者介面 (UI) 元素 Device.BeginInvokeOnMainThread(() => { // 在這裡更新 UI 控制項 labtime.Text = DateTime.Now.ToString("HH:mm:ss"); }); Thread.Sleep(1000); } while (!blnStop); } private async void OnCounterClicked(object sender, EventArgs e) { count++; if (count == 1) CounterBtn.Text = $"Clicked {count} time"; else CounterBtn.Text = $"Clicked {count} times"; await DisplayAlert("Alert", $"路徑:{AppDomain.CurrentDomain.BaseDirectory}", "OK");//await DataTable dtbuf = GetDataTable("vpos.db", "SELECT * FROM class_data"); //--- Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);//載入.net Big5編解碼函數庫(System.Text.Encoding.CodePages) StreamReader sr = new StreamReader(@"C:\Users\devel\Desktop\Input.json"); string StrInput = sr.ReadLine(); sr.Close();// 關閉串流 ESCPOS_Receipt_RS232Print(StrInput); //--- } private void OnPopupClicked(object sender, EventArgs e) { this.ShowPopup(new PopupPage()); } public static SerialPort m_port = new SerialPort(); public static void CommDataReceived(Object sender, SerialDataReceivedEventArgs e) { //https://www.cnblogs.com/xinaixia/p/6216745.html try { //Comm.BytesToRead中为要读入的字节长度 int len = m_port.BytesToRead; Byte[] readBuffer = new Byte[len]; m_port.Read(readBuffer, 0, len); //将数据读入缓存 //处理readBuffer中的数据,自定义处理过程 } catch (Exception ex) { } } static void ESCPOS_Receipt_RS232Print(String StrInput = "")//收據 { Console.WriteLine("Init Jint..."); var engine = new Engine(); engine.Execute(System.IO.File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "Script" + Path.DirectorySeparatorChar + "CommonFun.js")); engine.Execute(System.IO.File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "Script" + Path.DirectorySeparatorChar + "QrCode_57mm.js")); engine.SetValue("input", StrInput); Console.WriteLine("Create ESC_Command..."); String StrFunName = "Main()"; var Jsonresult = engine.Execute(StrFunName).GetCompletionValue(); ESCPOS_OrderNew ESCPOSCommand = new ESCPOS_OrderNew(); ESCPOSCommand = JsonSerializer.Deserialize<ESCPOS_OrderNew>(Jsonresult.AsString()); Console.WriteLine("C# Modified ESC_Command Start"); if ((ESCPOSCommand != null) && (ESCPOSCommand.state_code == 0) && (ESCPOSCommand.value != null) && (ESCPOSCommand.value.Count > 0)) { for (int i = 0; i < ESCPOSCommand.value.Count; i++) { ESCPOSCommand.value[i] = UnescapeUnicode(ESCPOSCommand.value[i]); } } Console.WriteLine("C# Modified ESC_Command End"); string[] m_comports;//= SerialPort.GetPortNames(); m_comports = SerialPort.GetPortNames(); if ((m_comports.Length > 0) && (!m_port.IsOpen)) { m_port.PortName = m_comports[0]; //m_port.BaudRate = 115200;//RP-700 ; m_port.BaudRate = 19200;//PDC325 m_port.DataBits = 8; m_port.StopBits = StopBits.One; m_port.Parity = Parity.None; m_port.ReadTimeout = 1; m_port.ReadTimeout = 3000; //单位毫秒 m_port.WriteTimeout = 3000; //单位毫秒 //串口控件成员变量,字面意思为接收字节阀值, //串口对象在收到这样长度的数据之后会触发事件处理函数 //一般都设为1 m_port.ReceivedBytesThreshold = 1; m_port.DataReceived += new SerialDataReceivedEventHandler(CommDataReceived); //设置数据接收事件(监听) m_port.Open(); Console.WriteLine("ESC_Command to Printer Start"); if ((ESCPOSCommand != null) && (ESCPOSCommand.value != null)) { for (int i = 0; i < ESCPOSCommand.value.Count; i++) { //會亂碼 byte[] bytes = Encoding.UTF8.GetBytes(ESCPOSCommand.value[i]); //會亂碼 byte[] bytes = Encoding.Default.GetBytes(ESCPOSCommand.value[i]); //會亂碼 byte[] bytes = Encoding.ASCII.GetBytes(ESCPOSCommand.value[i]); //會亂碼 byte[] bytes = Encoding.Latin1.GetBytes(ESCPOSCommand.value[i]); //byte[] bytes = Encoding.GetEncoding("big5").GetBytes(ESCPOSCommand.value[i]); m_port.Write(Encoding.GetEncoding("big5").GetBytes(ESCPOSCommand.value[i]), 0, Encoding.GetEncoding("big5").GetBytes(ESCPOSCommand.value[i]).Length); //m_port.Write(bytes, 0, bytes.Length); } } //*/ Console.WriteLine("ESC_Command to Printer End"); } else { m_port.Close(); } } private void OnClosed(object sender, EventArgs e) { if(timmer!=null) { timmer.Stop(); } if(thread!=null) { blnStop = true; thread = null; } // Close the active window //https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/windows Application.Current.CloseWindow(GetParentWindow()); } public static string UnescapeUnicode(string str) // 将unicode转义序列(\uxxxx)解码为字符串 { //GOOGLE: C# \uXXXX //https://www.cnblogs.com/netlog/p/15911016.html C#字符串Unicode转义序列编解码 //https://docs.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.unescape?view=net-6.0 //https://docs.microsoft.com/zh-tw/dotnet/api/system.text.regularexpressions.regex.unescape?view=net-6.0 return (System.Text.RegularExpressions.Regex.Unescape(str)); } public static SQLiteConnection OpenConn(string Database)//資料庫連線程式 { string cnstr = String.Format("Data Source={0};Version=3;", Database); SQLiteConnection icn = new SQLiteConnection(); icn.ConnectionString = cnstr; if (icn.State == ConnectionState.Open) { icn.Close(); icn = null; /*GC.Collect();*/ } icn.Open(); return icn; } public static DataTable GetDataTable(string Database, string SQLiteString)//讀取資料程式 { DataTable myDataTable = new DataTable(Database); try { SQLiteConnection icn = OpenConn(Database); SQLiteDataAdapter da = new SQLiteDataAdapter(SQLiteString, icn); DataSet ds = new DataSet(); ds.Clear(); da.Fill(ds); myDataTable = ds.Tables[0]; da.Dispose(); ds.Dispose(); da = null; ds = null; if (icn.State == ConnectionState.Open) { icn.Close(); icn = null; /*GC.Collect();*/ } if (true) { String StrLog = String.Format("{0}: {1};{2}", "sync_GetDataTable", SQLiteString, "success"); } } catch (Exception ex) { if (true) { String StrLog = String.Format("{0}: {1};{2}", "sync_GetDataTable", SQLiteString, ex.ToString()); } } return myDataTable; } } public class ESCPOS_OrderNew { public int state_code { get; set; } public List<string> value { get; set; } }
MauiProgram.cs
//--- //.net MAUI how to maximize application on startup //https://stackoverflow.com/questions/72128525/net-maui-how-to-maximize-application-on-startup using Microsoft.Maui.LifecycleEvents; using CommunityToolkit.Maui; #if WINDOWS using Microsoft.UI; using Microsoft.UI.Windowing; using Windows.Graphics; #endif //---.net MAUI how to maximize application on startup namespace MAUI_WinAPI_Object_test; public static class MauiProgram { public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .UseMauiCommunityToolkit() .ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); }); //--- //.net MAUI how to maximize application on startup https://stackoverflow.com/questions/72128525/net-maui-how-to-maximize-application-on-startup #if WINDOWS builder.ConfigureLifecycleEvents(events => { events.AddWindows(wndLifeCycleBuilder => { wndLifeCycleBuilder.OnWindowCreated(window => { IntPtr nativeWindowHandle = WinRT.Interop.WindowNative.GetWindowHandle(window); WindowId win32WindowsId = Win32Interop.GetWindowIdFromWindow(nativeWindowHandle); AppWindow winuiAppWindow = AppWindow.GetFromWindowId(win32WindowsId); if(winuiAppWindow.Presenter is OverlappedPresenter p) { p.Maximize(); } //--- //[Windows] How to completely hide the TitleBar? //https://github.com/dotnet/maui/issues/15142 window.ExtendsContentIntoTitleBar = false; switch (winuiAppWindow.Presenter) { case Microsoft.UI.Windowing.OverlappedPresenter overlappedPresenter: overlappedPresenter.SetBorderAndTitleBar(false, false); overlappedPresenter.Maximize(); break; } //---[Windows] How to completely hide the TitleBar? }); }); }); #endif //---.net MAUI how to maximize application on startup return builder.Build(); } }
2 thoughts on “C# WINDOWS MAUI專案 建立自訂彈出對話合視窗(Custom PopupPage/Dialog)”
MAUI Popups | MAUI Community Toolkit
範例程式: https://github.com/Skynet-Demos/MauiPopups
影片 收藏
Highly Customizable Popups for .NET MAUI with Mopups