Avalonia ListBox 程式刷新/更新 顯示資料(屬性觸發更新機制)
Avalonia ListBox 程式刷新/更新 顯示資料(屬性觸發更新機制)
資料來源: copilot/chatgpt
XMAL (Mode=TwoWay)
<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="{Binding ImageSource,Mode=TwoWay}" Width="50" Height="50" Margin="5" PointerPressed="Image_PointerPressed"/>
<TextBlock Text="{Binding user_account,Mode=TwoWay}" 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>
code(INotifyPropertyChanged)
using Avalonia.Media.Imaging;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Xml.Linq;
using static System.Net.Mime.MediaTypeNames;
namespace VPOS_Avalonia.ViewModels
{
public class LoginItem : INotifyPropertyChanged //ListBox 程式刷新顯示資料
{
public string role_sid { get; set; }
private string _user_account;//ListBox 程式刷新顯示資料
public string user_account
{//ListBox 程式刷新顯示資料
get => _user_account;
set
{
if (_user_account != value)
{
_user_account = value;
OnPropertyChanged(nameof(user_account));
}
}
}
public string user_pwd { get; set; }
public string employee_no { get; set; }
public string SID { get; set; }
private Bitmap _ImageSource;//ListBox 程式刷新顯示資料
public Bitmap ImageSource
{ //ListBox 程式刷新顯示資料
get => _ImageSource;
set
{
if (_ImageSource != value)
{
_ImageSource = value;
OnPropertyChanged(nameof(ImageSource));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
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
}
}
code(觸發事件)
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;
using Avalonia.Platform;
using Avalonia.Media.Imaging;
using Avalonia.Input;
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();//建構子函數中資源檔載入[InitializeComponent();]前必須指定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())
{
var stream = AssetLoader.Open(new Uri("avares://VPOS_Avalonia/Assets/user.png"));
Bitmap BitmapBuf = new Bitmap(stream);
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();
loginItemBuf.ImageSource = BitmapBuf;
((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;// 清除選擇狀態
}
}
// 處理Image的點擊事件
private void Image_PointerPressed(object sender, PointerPressedEventArgs e)
{
//*
//ListBox 程式刷新顯示資料 實驗程式碼
var stream = AssetLoader.Open(new Uri("avares://VPOS_Avalonia/Assets/vteam_logo.png"));//確定會變化實驗資料
Bitmap BitmapBuf = new Bitmap(stream);//確定會變化實驗資料
if (sender is Image image && image.DataContext is LoginItem item)
{
item.ImageSource = BitmapBuf;//確定會變化實驗資料
item.user_account = "test";//確定會變化實驗資料
}
//*/
}
}
One thought on “Avalonia ListBox 程式刷新/更新 顯示資料(屬性觸發更新機制)”
AvaloniaUI ListBox 新增/刪除 內容功能都有在此
GITHUB: https://github.com/jash-git/AvaloniaUI_CS_test 項目實現
修改刷新/更新 顯示資料 Listbox 項目 就是這篇文章