Avalonia(C#) 要使用ViewModels方式指定UI元件(ListBox)資料SOP

Avalonia(C#) 要使用ViewModels方式指定UI元件(ListBox)資料SOP

Avalonia(C#) 要使用ViewModels方式指定UI元件(ListBox)資料SOP


資料來源: VS2022標準預設官方範例~ MainWindowViewModel


ViewModels 使用步驟:

    ▲[固定語法(寫在axaml)] xmlns:vm=”using:VPOS_Avalonia.ViewModels”
    ▲[對應語法(寫在axaml)] x:DataType=”vm:LoginViewModel”
    ▲[對應語法(寫在axaml)] <Design.DataContext>
    ▲[對應語法(寫在cs)] DataContext = new LoginViewModel();//建構子函數中資源檔載入[InitializeComponent();]前必須指定ViewModel


[範例程式]

Login.axaml

<Window xmlns="https://github.com/avaloniaui"
        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"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
		xmlns:local="clr-namespace:VPOS_Avalonia"
        x:Class="VPOS_Avalonia.Login"
		xmlns:vm="using:VPOS_Avalonia.ViewModels"
		x:DataType="vm:LoginViewModel"
        Title="Login" Loaded="Login_Loaded">

	<!--
		ViewModels 使用步驟:
			▲[固定(axaml)] xmlns:vm="using:VPOS_Avalonia.ViewModels"
			▲[對應(axaml)] x:DataType="vm:LoginViewModel"
			▲[對應(axaml)] <Design.DataContext>
			▲[對應(cs)] DataContext = new LoginViewModel();//建構子函數中資源檔載入[InitializeComponent();]前必須指定ViewModel
	-->
	<Design.DataContext>
		<vm:LoginViewModel/>
	</Design.DataContext>
	
	<Grid x:Name="FullGrid" RowDefinitions ="45,6.4*,0.6*" ColumnDefinitions="*,*" Background="#194a6e" Margin="5,5,5,5">
		<local:BaseButton x:Name="Close" Grid.Row="0" Grid.Column="1"
		       TextSize="30" Text="X" TextColor="White" BackgroundColor="#194a6e" BorderColor="#194a6e"
			   Width="45" Height="45" HorizontalAlignment="Right" VerticalAlignment="Top" ExternalClicked="Close_Clicked"/>
		
		<Grid x:Name="LeftGrid" Grid.Row="1" Grid.Column="0" Margin="13,10,13,21">
			<Border BorderBrush="White" BorderThickness="1" CornerRadius="10" >
				<ListBox x:Name="lvUser" SelectionMode="Single" ItemsSource="{Binding Items}" Background="White" SelectionChanged="lvUser_ItemSelected">
					<ListBox.ItemTemplate>
						<DataTemplate>
							<StackPanel Orientation="Horizontal" Spacing="10" Margin="5">
								<Image Source="/Assets/user.png" Width="50" Height="50" Margin="5"/>
								<TextBlock Text="{Binding user_account}" FontSize="35" VerticalAlignment="Center" Margin="5"/>
							</StackPanel>
						</DataTemplate>
					</ListBox.ItemTemplate>
				</ListBox>
			</Border>
		</Grid>
		<Grid x:Name="RightGrid" Grid.Row="1" Grid.Column="1"  RowDefinitions ="1*,4*" Margin="13,10,13,21">
			<Border Grid.Row="0" BorderBrush="White" BorderThickness="1" CornerRadius="10" Margin="0,0,0,15">
				<Grid RowDefinitions ="*,*">
					<TextBlock x:Name="labUserName" Grid.Row="0" Text="" FontSize="35" VerticalAlignment="Center" Foreground="White" Margin="20,5"/>
					<TextBox x:Name="txtPassword" Grid.Row="1" PasswordChar="●" FontSize="40" Background="LightBlue" VerticalContentAlignment="Center" Watermark="Enter password" Margin="20,5" TextChanged ="txtPassword_TextChanged"/>
				</Grid>
			</Border>
			<Border Grid.Row="1" BorderBrush="White" BorderThickness="1" CornerRadius="10" Margin="0,5,0,0">
				<Grid RowDefinitions ="*,*,*,*" ColumnDefinitions="*,*,*,*">
					<local:BaseButton x:Name="Num01" Grid.Row="0" Grid.Column="0" Margin="10,10,10,10"
						   TextSize="30" Text="1" TextColor="White" BackgroundColor="#194a6e" BorderColor="White"
						   HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ExternalClicked="NumberBtn_Clicked"/>
					<local:BaseButton x:Name="Num02" Grid.Row="0" Grid.Column="1" Margin="10,10,10,10"
						   TextSize="30" Text="2" TextColor="White" BackgroundColor="#194a6e" BorderColor="White"
						   HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ExternalClicked="NumberBtn_Clicked"/>
					<local:BaseButton x:Name="Num03" Grid.Row="0" Grid.Column="2" Margin="10,10,10,10"
						   TextSize="30" Text="3" TextColor="White" BackgroundColor="#194a6e" BorderColor="White"
						   HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ExternalClicked="NumberBtn_Clicked"/>
					<Grid Grid.Row="0" Grid.Column="3" Grid.RowSpan="3" RowDefinitions ="*,*">
						<local:BaseButton x:Name="BtnC" Grid.Row="0" Margin="10,10,10,10"
							   TextSize="30" Text="C" TextColor="White" BackgroundColor="#194a6e" BorderColor="White"
							   HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ExternalClicked="BtnClear_Clicked"/>
						<local:BaseButton x:Name="BtnDel" Grid.Row="1" Margin="10,10,10,10"
							   TextSize="30" Text="Del" TextColor="White" BackgroundColor="#194a6e" BorderColor="White"
							   HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ExternalClicked="BtnDelete_Clicked"/>						
					</Grid>
						
					<local:BaseButton x:Name="Num04" Grid.Row="1" Grid.Column="0" Margin="10,10,10,10"
						   TextSize="30" Text="4" TextColor="White" BackgroundColor="#194a6e" BorderColor="White"
						   HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ExternalClicked="NumberBtn_Clicked"/>
					<local:BaseButton x:Name="Num05" Grid.Row="1" Grid.Column="1" Margin="10,10,10,10"
						   TextSize="30" Text="5" TextColor="White" BackgroundColor="#194a6e" BorderColor="White"
						   HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ExternalClicked="NumberBtn_Clicked"/>
					<local:BaseButton x:Name="Num06" Grid.Row="1" Grid.Column="2" Margin="10,10,10,10"
						   TextSize="30" Text="6" TextColor="White" BackgroundColor="#194a6e" BorderColor="White"
						   HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ExternalClicked="NumberBtn_Clicked"/>

					<local:BaseButton x:Name="Num07" Grid.Row="2" Grid.Column="0" Margin="10,10,10,10"
						   TextSize="30" Text="7" TextColor="White" BackgroundColor="#194a6e" BorderColor="White"
						   HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ExternalClicked="NumberBtn_Clicked"/>
					<local:BaseButton x:Name="Num08" Grid.Row="2" Grid.Column="1" Margin="10,10,10,10"
						   TextSize="30" Text="8" TextColor="White" BackgroundColor="#194a6e" BorderColor="White"
						   HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ExternalClicked="NumberBtn_Clicked"/>
					<local:BaseButton x:Name="Num09" Grid.Row="2" Grid.Column="2" Margin="10,10,10,10"
						   TextSize="30" Text="9" TextColor="White" BackgroundColor="#194a6e" BorderColor="White"
						   HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ExternalClicked="NumberBtn_Clicked"/>
					<Grid  Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="4" ColumnDefinitions ="*,*">
						<local:BaseButton x:Name="Num00" Grid.Column="0" Margin="10,10,10,10"
							   TextSize="30" Text="0" TextColor="White" BackgroundColor="#194a6e" BorderColor="White"
							   HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ExternalClicked="NumberBtn_Clicked"/>
						<local:BaseButton x:Name="BtnLogin" Grid.Column="1" Margin="10,10,10,10"
							   TextSize="30" Text="登入" TextColor="White" BackgroundColor="#194a6e" BorderColor="White"
							   HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ExternalClicked="BtnEnter_Clicked"/>
					</Grid>
				</Grid>
			</Border>
		</Grid>
		<Grid x:Name="EndGrid" Grid.Row="2" Grid.Column="0" Margin="20,5,20,15" ColumnDefinitions ="*,*" >
			<local:ImageButton x:Name="ResetBtn" Grid.Row="0" Grid.Column="0"
								TextSize="30" Text="重新開機" TextColor="White" BackgroundColor="#194a6e" BorderColor="White"
						        ImageSource="/Assets/reset.png"
							    Width="200" VerticalAlignment="Stretch" ExternalClicked="ResetBtn_Clicked"/>
			<local:ImageButton x:Name="ShutdownBtn" Grid.Row="0" Grid.Column="1"
								TextSize="30" Text="關        機" TextColor="White" BackgroundColor="#194a6e" BorderColor="White"
						        ImageSource="/Assets/shutdown.png"
							    Width="200" VerticalAlignment="Stretch" ExternalClicked="ShutdownBtn_Clicked"/>			
		</Grid>
	</Grid>
</Window>

LoginViewModel.cs

using System.Collections.ObjectModel;

namespace VPOS_Avalonia.ViewModels
{
    public class LoginItem
    {
        public string role_sid { get; set; }
        public string user_account { get; set; }
        public string user_pwd { get; set; }
        public string employee_no { get; set; }
        public string SID { get; set; }
    }

    public partial class LoginViewModel : ViewModelBase
    {
#pragma warning disable CA1822 // Mark members as static
        public ObservableCollection<LoginItem> Items { get; set; }= new ObservableCollection<LoginItem>();
        public string Text => "Welcome to Avalonia!";
#pragma warning restore CA1822 // Mark members as static
    }
}

Login.axaml.cs

using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using VPOS;
using VPOS_Avalonia.Views;
using VPOS_Avalonia.ViewModels;
namespace VPOS_Avalonia;


public partial class Login : Window
{

    public static bool m_blnCloseApp = true;
    public String m_StrPIN = "";
    public String m_Strrole_sid = "";
    public Login()
    {
        DataContext = new LoginViewModel();//資源檔載入前必須指定ViewModel

        ExternalPopup.login = this;

        this.WindowState = WindowState.FullScreen;
        //隱藏工具列
        this.ExtendClientAreaToDecorationsHint = true;
        this.ExtendClientAreaTitleBarHeightHint = -1;
        this.SystemDecorations = SystemDecorations.None;
        //---隱藏工具列

        this.Background = new SolidColorBrush(Color.Parse("#194a6e"));//設定背景色
        this.BorderBrush = Brushes.Blue;//設定藍色邊框
        this.BorderThickness = new Thickness(2);//設定邊框寬度

        InitializeComponent();

        //---
        //資源檔載入的後續調整
        if (MainWindow.m_dblScreenWidth != 1920)
        {
            txtPassword.FontSize = txtPassword.FontSize * 2 / 3;
        }
        //---資源檔載入的後續調整

    }
    private void Login_Loaded(object sender, RoutedEventArgs e)
    {
        LogFile.Write("LoginPage Start");        
        if (SQLDataTableModel.user_dataLoad())
        {
            LogFile.Write("Have login accounts");
            for (int i = 0; i < SQLDataTableModel.m_user_dataDataTable.Rows.Count; i++)
            {
                LoginItem loginItemBuf = new LoginItem();
                loginItemBuf.role_sid = SQLDataTableModel.m_user_dataDataTable.Rows[i]["role_sid"].ToString();
                loginItemBuf.user_account = SQLDataTableModel.m_user_dataDataTable.Rows[i]["user_account"].ToString();
                loginItemBuf.user_pwd = SQLDataTableModel.m_user_dataDataTable.Rows[i]["user_pwd"].ToString();
                loginItemBuf.employee_no = SQLDataTableModel.m_user_dataDataTable.Rows[i]["employee_no"].ToString();
                loginItemBuf.SID = SQLDataTableModel.m_user_dataDataTable.Rows[i]["SID"].ToString();
                ((LoginViewModel)(this.DataContext)).Items.Add(loginItemBuf);
            }
            
            if(SQLDataTableModel.m_user_dataDataTable.Rows.Count>0)
            {
                lvUser.SelectedIndex = 0;
            }
        }
    }
    private async void ResetBtn_Clicked(object sender, RoutedEventArgs e)
    {
        await ExternalPopup.QuesMessageBox(2, "確定要執行重新開機動作?");
        if (QuesMessageBox.m_blnResult)
        {
            LogFile.Write("Reset PC");
            Process.Start("shutdown.exe", "/r /t 0");//重啟 ~ https://blog.csdn.net/xinbadar/article/details/78819565
        }
    }
    private async void ShutdownBtn_Clicked(object sender, RoutedEventArgs e)
    {
        await ExternalPopup.QuesMessageBox(2, "確定要執行關機動作?");
        if (QuesMessageBox.m_blnResult)
        {
            LogFile.Write("Shutdown PC");
            Process.Start("shutdown.exe", "/s /t 0");//關機 ~ https://blog.csdn.net/xinbadar/article/details/78819565
        }
    }
    private void Close_Clicked(object sender, RoutedEventArgs e)
    {
        this.Close();
    }
    private void ShowMainUI()
    {
        if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
        {
            MainWindow MainUI = new MainWindow();
            m_blnCloseApp = false;
            desktop.MainWindow = MainUI;
            MainUI.Show();
            this.Close();
        }
    }
    private void txtPassword_TextChanged(object sender, TextChangedEventArgs e)
    {
        txtPassword.Text = Regex.Replace(txtPassword.Text, "[^0-9]", "");//限制登入密碼只能是數字
    }
    private void NumberBtn_Clicked(object sender, RoutedEventArgs e)
    {
        txtPassword.Text += ((BaseButton)(sender)).Text;
        txtPassword.Focus();
    }
    private void BtnDelete_Clicked(object sender, RoutedEventArgs e)
    {
        if (txtPassword.Text.Length > 0)
        {
            txtPassword.Text = txtPassword.Text.Substring(0, txtPassword.Text.Length - 1);
        }
        txtPassword.Focus();
    }
    private void BtnClear_Clicked(object sender, RoutedEventArgs e)
    {
        txtPassword.Text = "";
        txtPassword.Focus();
    }
    private async void BtnEnter_Clicked(object sender, RoutedEventArgs e)
    {
        String StrPIN = "";
        if ((txtPassword.Text != null) && (txtPassword.Text.Length > 0))
        {
            try
            {
                SHA256 sha256 = new SHA256CryptoServiceProvider();//建立一個SHA256
                byte[] source = Encoding.Default.GetBytes(txtPassword.Text);//將字串轉為Byte[]
                byte[] crypto = sha256.ComputeHash(source);

                for (int i = 0; i < crypto.Length; i++)//BYTE陣列資料 變成 16進制
                {
                    StrPIN += Convert.ToString(crypto[i], 16).PadLeft(2, '0');
                }
            }
            catch (Exception ex)
            {
                StrPIN = "";
            }
        }

        if (m_StrPIN == StrPIN)
        {
            //---
            //載入func_main資料表的資訊到購物車UI的對應成員變數中
            MainWindow.m_funcMain.Clear();
            String SQL = String.Format("SELECT fm.SID AS SID,fm.func_name AS Name,IFNULL(rf.role_sid,0) AS Eenabe FROM func_main AS fm LEFT JOIN role_func AS rf ON (fm.SID=rf.func_sid) AND (rf.role_sid='{0}')", m_Strrole_sid);
            DataTable dt = SQLDataTableModel.GetDataTable(SQL);
            if ((dt != null) && (dt.Rows.Count > 0))
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    MainWindow.m_funcMain.Add(new func_mainData(dt.Rows[i]["SID"].ToString(), dt.Rows[i]["Name"].ToString(), (dt.Rows[i]["Eenabe"].ToString() == "0") ? false : true));
                }
            }
            //---載入func_main資料表的資訊到購物車UI的對應成員變數中

            POS_INVAPI.m_blnAutoCheck = (App.m_intNetworkLevel > 0) ? true : false;//是否自動偵測
            POS_ECMAPI.m_blnRunInit = true;//登入成功就執行悠遊卡設備初始化
            NCCCAPI.m_blnRunInit = true;//聯信卡機初始偵測
            MainWindow.m_blnShowDailyQuestion = true;//自動營業關帳提示訊息旗標
            LogFile.Write("Sign in suceesfully");
            LogFile.Write("LoginPage End");

            ShowMainUI();

        }
        else
        {
            String StrMsg = "";
            if ((txtPassword.Text != null) && (txtPassword.Text.Length > 0))
            {
                StrMsg = "使用者密碼驗證失敗";
            }
            else
            {
                StrMsg = "請輸入密碼";
            }
            LogFile.Write("Login failed");
            await ExternalPopup.MessageBox(2, StrMsg);

        }
    }
    private void lvUser_ItemSelected(object sender, SelectionChangedEventArgs e)
    {
        if (lvUser.SelectedItem !=null)
        {
            LogFile.Write("Switch login account");
            labUserName.Text = ((LoginItem)lvUser.SelectedItem).user_account;//await this.ShowPopupAsync(new MessageBox(selectedItem.Text));
            m_Strrole_sid = ((LoginItem)lvUser.SelectedItem).role_sid;
            m_StrPIN = ((LoginItem)lvUser.SelectedItem).user_pwd;
            MainWindow.m_StrEmployeeNo = ((LoginItem)lvUser.SelectedItem).employee_no;
            MainWindow.m_StrUserAccount = ((LoginItem)lvUser.SelectedItem).user_account;
            MainWindow.m_StrUserSID = ((LoginItem)lvUser.SelectedItem).SID;
            //lvUser.SelectedItem = null;// 清除選擇狀態
        }

    }

}

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *