리크 테스트 gui
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

100 lines
4.1 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
using System.Windows.Threading;
using leak_test_project.Models;
using leak_test_project.Services;
using leak_test_project.ViewModels.Core;
namespace leak_test_project.ViewModels
{
/// <summary>
/// In/Out Monitor 화면의 데이터 페이징 및 실시간 갱신 로직을 담당하는 ViewModel.
/// </summary>
public class InOutViewModel : ObservableObject, IDisposable
{
private readonly IoBoardService _ioService;
private readonly List<InOutItem> _allInputs;
private readonly List<InOutItem> _allOutputs;
private const int PageSize = 30;
private int _inputCurrentPage = 0;
private int _outputCurrentPage = 0;
private readonly DispatcherTimer _refreshTimer;
private List<InOutItem> _currentInputs = new List<InOutItem>();
public List<InOutItem> CurrentInputs { get => _currentInputs; set => SetProperty(ref _currentInputs, value); }
private List<InOutItem> _currentOutputs = new List<InOutItem>();
public List<InOutItem> CurrentOutputs { get => _currentOutputs; set => SetProperty(ref _currentOutputs, value); }
// Input 페이징 커맨드
public ICommand InputFirstCommand { get; }
public ICommand InputPrevCommand { get; }
public ICommand InputNextCommand { get; }
public ICommand InputLastCommand { get; }
// Output 페이징 커맨드
public ICommand OutputFirstCommand { get; }
public ICommand OutputPrevCommand { get; }
public ICommand OutputNextCommand { get; }
public ICommand OutputLastCommand { get; }
/// <summary> Close 버튼 시 홈으로 돌아가는 커맨드 </summary>
public ICommand CloseCommand { get; }
public InOutViewModel(Action navigateHome, IoBoardService ioService)
{
_ioService = ioService;
_allInputs = ioService.Inputs;
_allOutputs = ioService.Outputs;
InputFirstCommand = new RelayCommand(o => { _inputCurrentPage = 0; UpdateInputs(); });
InputPrevCommand = new RelayCommand(o => { if (_inputCurrentPage > 0) { _inputCurrentPage--; UpdateInputs(); } });
InputNextCommand = new RelayCommand(o => { if ((_inputCurrentPage + 1) * PageSize < _allInputs.Count) { _inputCurrentPage++; UpdateInputs(); } });
InputLastCommand = new RelayCommand(o => { _inputCurrentPage = Math.Max(0, (_allInputs.Count - 1) / PageSize); UpdateInputs(); });
OutputFirstCommand = new RelayCommand(o => { _outputCurrentPage = 0; UpdateOutputs(); });
OutputPrevCommand = new RelayCommand(o => { if (_outputCurrentPage > 0) { _outputCurrentPage--; UpdateOutputs(); } });
OutputNextCommand = new RelayCommand(o => { if ((_outputCurrentPage + 1) * PageSize < _allOutputs.Count) { _outputCurrentPage++; UpdateOutputs(); } });
OutputLastCommand = new RelayCommand(o => { _outputCurrentPage = Math.Max(0, (_allOutputs.Count - 1) / PageSize); UpdateOutputs(); });
CloseCommand = new RelayCommand(o => {
Dispose();
navigateHome?.Invoke();
});
UpdateInputs();
UpdateOutputs();
// 500ms 주기로 DIO 상태 자동 갱신
_refreshTimer = new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(500)
};
_refreshTimer.Tick += (s, e) =>
{
_ioService.RefreshState();
// InOutItem이 INotifyPropertyChanged를 구현하므로 더 이상 리스트를 재생성할 필요가 없습니다.
};
_refreshTimer.Start();
}
private void UpdateInputs()
{
CurrentInputs = _allInputs.Skip(_inputCurrentPage * PageSize).Take(PageSize).ToList();
}
private void UpdateOutputs()
{
CurrentOutputs = _allOutputs.Skip(_outputCurrentPage * PageSize).Take(PageSize).ToList();
}
public void Dispose()
{
_refreshTimer?.Stop();
}
}
}