582 lines
20 KiB
C#
582 lines
20 KiB
C#
|
|
using MainShell.Common;
|
||
|
|
using MainShell.Hardware;
|
||
|
|
using MainShell.Log;
|
||
|
|
using MainShell.Manual.Model;
|
||
|
|
using MainShell.Models;
|
||
|
|
using MainShell.Motion;
|
||
|
|
using MainShell.Process;
|
||
|
|
using MainShell.ProcessResult;
|
||
|
|
using MainShell.Recipe.Models;
|
||
|
|
using MainShell.Resources.CustomControl;
|
||
|
|
using MwFramework.ManagerService;
|
||
|
|
using Stylet;
|
||
|
|
using StyletIoC;
|
||
|
|
using System;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.Collections.ObjectModel;
|
||
|
|
using System.Linq;
|
||
|
|
using System.Threading.Tasks;
|
||
|
|
using System.Windows;
|
||
|
|
using MW.WorkFlow;
|
||
|
|
|
||
|
|
namespace MainShell.Manual.ViewModel
|
||
|
|
{
|
||
|
|
public class DieRecheckDisplayItem : PropertyChangedBase
|
||
|
|
{
|
||
|
|
private int _stepIndex;
|
||
|
|
public int StepIndex
|
||
|
|
{
|
||
|
|
get { return _stepIndex; }
|
||
|
|
set { SetAndNotify(ref _stepIndex, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private int _padRow;
|
||
|
|
public int PadRow
|
||
|
|
{
|
||
|
|
get { return _padRow; }
|
||
|
|
set { SetAndNotify(ref _padRow, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private int _padColumn;
|
||
|
|
public int PadColumn
|
||
|
|
{
|
||
|
|
get { return _padColumn; }
|
||
|
|
set { SetAndNotify(ref _padColumn, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private int _dieRow;
|
||
|
|
public int DieRow
|
||
|
|
{
|
||
|
|
get { return _dieRow; }
|
||
|
|
set { SetAndNotify(ref _dieRow, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private int _dieColumn;
|
||
|
|
public int DieColumn
|
||
|
|
{
|
||
|
|
get { return _dieColumn; }
|
||
|
|
set { SetAndNotify(ref _dieColumn, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private double _padX;
|
||
|
|
public double PadX
|
||
|
|
{
|
||
|
|
get { return _padX; }
|
||
|
|
set { SetAndNotify(ref _padX, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private double _padY;
|
||
|
|
public double PadY
|
||
|
|
{
|
||
|
|
get { return _padY; }
|
||
|
|
set { SetAndNotify(ref _padY, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private double _dieX;
|
||
|
|
public double DieX
|
||
|
|
{
|
||
|
|
get { return _dieX; }
|
||
|
|
set { SetAndNotify(ref _dieX, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private double _dieY;
|
||
|
|
public double DieY
|
||
|
|
{
|
||
|
|
get { return _dieY; }
|
||
|
|
set { SetAndNotify(ref _dieY, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private string _transPathType;
|
||
|
|
public string TransPathType
|
||
|
|
{
|
||
|
|
get { return _transPathType; }
|
||
|
|
set { SetAndNotify(ref _transPathType, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private bool _isMissingBond;
|
||
|
|
public bool IsMissingBond
|
||
|
|
{
|
||
|
|
get { return _isMissingBond; }
|
||
|
|
set { SetAndNotify(ref _isMissingBond, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private double _xError;
|
||
|
|
public double XError
|
||
|
|
{
|
||
|
|
get { return _xError; }
|
||
|
|
set { SetAndNotify(ref _xError, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private double _yError;
|
||
|
|
public double YError
|
||
|
|
{
|
||
|
|
get { return _yError; }
|
||
|
|
set { SetAndNotify(ref _yError, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private bool _isXThresholdExceeded;
|
||
|
|
public bool IsXThresholdExceeded
|
||
|
|
{
|
||
|
|
get { return _isXThresholdExceeded; }
|
||
|
|
set { SetAndNotify(ref _isXThresholdExceeded, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private bool _isYThresholdExceeded;
|
||
|
|
public bool IsYThresholdExceeded
|
||
|
|
{
|
||
|
|
get { return _isYThresholdExceeded; }
|
||
|
|
set { SetAndNotify(ref _isYThresholdExceeded, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private string _statusSummary;
|
||
|
|
public string StatusSummary
|
||
|
|
{
|
||
|
|
get { return _statusSummary; }
|
||
|
|
set { SetAndNotify(ref _statusSummary, value); }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public class DieRecheckFilterState : PropertyChangedBase
|
||
|
|
{
|
||
|
|
private enum DieRecheckFilterRule
|
||
|
|
{
|
||
|
|
None = 0,
|
||
|
|
MissingBondOnly,
|
||
|
|
XThresholdExceededOnly,
|
||
|
|
YThresholdExceededOnly,
|
||
|
|
XYThresholdExceededOnly
|
||
|
|
}
|
||
|
|
|
||
|
|
private DieRecheckFilterRule _selectedRule;
|
||
|
|
private bool _isUpdatingSelection;
|
||
|
|
|
||
|
|
public bool IsMissingBondRuleSelected
|
||
|
|
{
|
||
|
|
get { return _selectedRule == DieRecheckFilterRule.MissingBondOnly; }
|
||
|
|
set { SetSelectedRule(value, DieRecheckFilterRule.MissingBondOnly, nameof(IsMissingBondRuleSelected)); }
|
||
|
|
}
|
||
|
|
|
||
|
|
public bool IsXThresholdRuleSelected
|
||
|
|
{
|
||
|
|
get { return _selectedRule == DieRecheckFilterRule.XThresholdExceededOnly; }
|
||
|
|
set { SetSelectedRule(value, DieRecheckFilterRule.XThresholdExceededOnly, nameof(IsXThresholdRuleSelected)); }
|
||
|
|
}
|
||
|
|
|
||
|
|
public bool IsYThresholdRuleSelected
|
||
|
|
{
|
||
|
|
get { return _selectedRule == DieRecheckFilterRule.YThresholdExceededOnly; }
|
||
|
|
set { SetSelectedRule(value, DieRecheckFilterRule.YThresholdExceededOnly, nameof(IsYThresholdRuleSelected)); }
|
||
|
|
}
|
||
|
|
|
||
|
|
public bool IsXYThresholdRuleSelected
|
||
|
|
{
|
||
|
|
get { return _selectedRule == DieRecheckFilterRule.XYThresholdExceededOnly; }
|
||
|
|
set { SetSelectedRule(value, DieRecheckFilterRule.XYThresholdExceededOnly, nameof(IsXYThresholdRuleSelected)); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private double _xThreshold = 0.01d;
|
||
|
|
public double XThreshold
|
||
|
|
{
|
||
|
|
get { return _xThreshold; }
|
||
|
|
set { SetAndNotify(ref _xThreshold, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private double _yThreshold = 0.01d;
|
||
|
|
public double YThreshold
|
||
|
|
{
|
||
|
|
get { return _yThreshold; }
|
||
|
|
set { SetAndNotify(ref _yThreshold, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
public void ClearSelectedRule()
|
||
|
|
{
|
||
|
|
UpdateSelectedRule(DieRecheckFilterRule.None, null);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void SetSelectedRule(bool isSelected, DieRecheckFilterRule targetRule, string propertyName)
|
||
|
|
{
|
||
|
|
if (_isUpdatingSelection)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
DieRecheckFilterRule newRule = isSelected ? targetRule : DieRecheckFilterRule.None;
|
||
|
|
UpdateSelectedRule(newRule, propertyName);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void UpdateSelectedRule(DieRecheckFilterRule newRule, string propertyName)
|
||
|
|
{
|
||
|
|
if (_selectedRule == newRule)
|
||
|
|
{
|
||
|
|
if (!string.IsNullOrWhiteSpace(propertyName))
|
||
|
|
{
|
||
|
|
OnPropertyChanged(propertyName);
|
||
|
|
}
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
_selectedRule = newRule;
|
||
|
|
_isUpdatingSelection = true;
|
||
|
|
try
|
||
|
|
{
|
||
|
|
OnPropertyChanged(nameof(IsMissingBondRuleSelected));
|
||
|
|
OnPropertyChanged(nameof(IsXThresholdRuleSelected));
|
||
|
|
OnPropertyChanged(nameof(IsYThresholdRuleSelected));
|
||
|
|
OnPropertyChanged(nameof(IsXYThresholdRuleSelected));
|
||
|
|
}
|
||
|
|
finally
|
||
|
|
{
|
||
|
|
_isUpdatingSelection = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public class DieRecheckViewModel : OperateViewModelBase
|
||
|
|
{
|
||
|
|
private readonly IEventAggregator _eventAggregator;
|
||
|
|
private readonly RecipeManager _recipeManager;
|
||
|
|
private readonly ProcessResultManager _processResultManager;
|
||
|
|
private readonly DieRecheckService _dieRecheckService;
|
||
|
|
private readonly SafeAxisMotion _safeAxisMotion;
|
||
|
|
|
||
|
|
private ObservableCollection<DieRecheckDisplayItem> _allPointResults = new ObservableCollection<DieRecheckDisplayItem>();
|
||
|
|
private List<DieRecheckDisplayItem> _filteredPointResults = new List<DieRecheckDisplayItem>();
|
||
|
|
|
||
|
|
private ObservableCollection<DieRecheckDisplayItem> _pointResults = new ObservableCollection<DieRecheckDisplayItem>();
|
||
|
|
public ObservableCollection<DieRecheckDisplayItem> PointResults
|
||
|
|
{
|
||
|
|
get { return _pointResults; }
|
||
|
|
set { SetAndNotify(ref _pointResults, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
public PaginationViewModel Pagination { get; } = new PaginationViewModel();
|
||
|
|
|
||
|
|
private RegionModel _recheckRegion = new RegionModel();
|
||
|
|
public RegionModel RecheckRegion
|
||
|
|
{
|
||
|
|
get { return _recheckRegion; }
|
||
|
|
set { SetAndNotify(ref _recheckRegion, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private DieRecheckFilterState _filterState = new DieRecheckFilterState();
|
||
|
|
public DieRecheckFilterState FilterState
|
||
|
|
{
|
||
|
|
get { return _filterState; }
|
||
|
|
set { SetAndNotify(ref _filterState, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private int _pointCount;
|
||
|
|
public int PointCount
|
||
|
|
{
|
||
|
|
get { return _pointCount; }
|
||
|
|
set { SetAndNotify(ref _pointCount, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private int _filteredPointCount;
|
||
|
|
public int FilteredPointCount
|
||
|
|
{
|
||
|
|
get { return _filteredPointCount; }
|
||
|
|
set { SetAndNotify(ref _filteredPointCount, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
private DieRecheckDisplayItem _selectedPointResult;
|
||
|
|
public DieRecheckDisplayItem SelectedPointResult
|
||
|
|
{
|
||
|
|
get { return _selectedPointResult; }
|
||
|
|
set { SetAndNotify(ref _selectedPointResult, value); }
|
||
|
|
}
|
||
|
|
|
||
|
|
public DieRecheckViewModel(
|
||
|
|
IEventAggregator eventAggregator,
|
||
|
|
RecipeManager recipeManager,
|
||
|
|
ProcessResultManager processResultManager,
|
||
|
|
HardwareManager hardwareManager,
|
||
|
|
DieRecheckService dieRecheckService,
|
||
|
|
SafeAxisMotion safeAxisMotion)
|
||
|
|
{
|
||
|
|
_eventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
|
||
|
|
_recipeManager = recipeManager ?? throw new ArgumentNullException(nameof(recipeManager));
|
||
|
|
_processResultManager = processResultManager ?? throw new ArgumentNullException(nameof(processResultManager));
|
||
|
|
if (hardwareManager == null)
|
||
|
|
{
|
||
|
|
throw new ArgumentNullException(nameof(hardwareManager));
|
||
|
|
}
|
||
|
|
_dieRecheckService = dieRecheckService ?? throw new ArgumentNullException(nameof(dieRecheckService));
|
||
|
|
_safeAxisMotion = safeAxisMotion ?? throw new ArgumentNullException(nameof(safeAxisMotion));
|
||
|
|
|
||
|
|
_cameraAxisViewModel = IoC.Get<Common.Display.ViewModel.CameraAxisViewModel>();
|
||
|
|
_cameraAxisViewModel.CameraAxisDevices.HardwareDeviceList = hardwareManager.CameraAxisManager.TopCameraAxisDevices;
|
||
|
|
|
||
|
|
FilterState.PropertyChanged += FilterState_PropertyChanged;
|
||
|
|
RecheckRegion.PropertyChanged += RecheckRegion_PropertyChanged;
|
||
|
|
Pagination.PageChanged += Pagination_PageChanged;
|
||
|
|
|
||
|
|
LoadCurrentPoints();
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override void OnViewLoaded()
|
||
|
|
{
|
||
|
|
base.OnViewLoaded();
|
||
|
|
LoadCurrentPoints();
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task StartProcess()
|
||
|
|
{
|
||
|
|
WorkflowContext context = new WorkflowContext();
|
||
|
|
context[WorkflowContextKeys.EventAggregator] = _eventAggregator;
|
||
|
|
context[WorkflowContextKeys.RecipeManager] = _recipeManager;
|
||
|
|
context[WorkflowContextKeys.ProcessResultManager] = _processResultManager;
|
||
|
|
context[WorkflowContextKeys.WorkflowName] = ProcessFlowName.DieRecheckFlow;
|
||
|
|
|
||
|
|
WorkflowRunCompletedEventArgs result = await RunManualActivityAsync(
|
||
|
|
new DieRecheckActivity(ProcessFlowName.DieRecheckFlow, _dieRecheckService),
|
||
|
|
context,
|
||
|
|
false);
|
||
|
|
|
||
|
|
if (!IsWorkflowCompleted(result))
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
LoadCurrentPoints();
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task MoveToSelectedPoint()
|
||
|
|
{
|
||
|
|
if (SelectedPointResult == null)
|
||
|
|
{
|
||
|
|
LocalizedMessageBox.Show(MessageKey.DieRecheckSelectedPointRequired, MessageKey.TitleWarning, MessageBoxButton.OK, MessageBoxImage.Warning);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
try
|
||
|
|
{
|
||
|
|
HardwareDevice selectedDevice = _cameraAxisViewModel.CameraAxisDevices != null
|
||
|
|
? _cameraAxisViewModel.CameraAxisDevices.SelectedHardwareDevice
|
||
|
|
: null;
|
||
|
|
if (selectedDevice == null || selectedDevice.AxisX == null || selectedDevice.AxisY == null)
|
||
|
|
{
|
||
|
|
LocalizedMessageBox.Show(MessageKey.DieRecheckMoveDeviceUnavailable, MessageKey.TitleWarning, MessageBoxButton.OK, MessageBoxImage.Warning);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
string moveMessage = $"DieRecheck move to point. StepIndex={SelectedPointResult.StepIndex}, PadX={SelectedPointResult.PadX:F4}, PadY={SelectedPointResult.PadY:F4}";
|
||
|
|
moveMessage.LogProcessInfo();
|
||
|
|
|
||
|
|
await Task.Run(() =>
|
||
|
|
_safeAxisMotion.SafeMove(
|
||
|
|
MotionMoveRequest.ForAxis(selectedDevice.AxisX, SelectedPointResult.PadX, source: nameof(DieRecheckViewModel), tags: new[] { "DieRecheck", "MoveToPoint", "AxisX" }),
|
||
|
|
MotionMoveRequest.ForAxis(selectedDevice.AxisY, SelectedPointResult.PadY, source: nameof(DieRecheckViewModel), tags: new[] { "DieRecheck", "MoveToPoint", "AxisY" })));
|
||
|
|
}
|
||
|
|
catch (Exception exception)
|
||
|
|
{
|
||
|
|
LogManager.LogSysError(exception);
|
||
|
|
MwMessageBox.Show(exception.Message, LanguageResourceHelper.GetString(MessageKey.TitleError), MessageBoxButton.OK, MessageBoxImage.Error);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public void ResetFilters()
|
||
|
|
{
|
||
|
|
FilterState.ClearSelectedRule();
|
||
|
|
FilterState.XThreshold = 0.01d;
|
||
|
|
FilterState.YThreshold = 0.01d;
|
||
|
|
ApplyFilters();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void FilterState_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||
|
|
{
|
||
|
|
UpdateThresholdFlags();
|
||
|
|
Pagination.CurrentPage = 1;
|
||
|
|
ApplyFilters();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void RecheckRegion_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||
|
|
{
|
||
|
|
Pagination.CurrentPage = 1;
|
||
|
|
ApplyFilters();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void Pagination_PageChanged(object sender, EventArgs e)
|
||
|
|
{
|
||
|
|
LoadPagedData();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void LoadCurrentPoints()
|
||
|
|
{
|
||
|
|
_allPointResults.Clear();
|
||
|
|
_filteredPointResults.Clear();
|
||
|
|
PointResults.Clear();
|
||
|
|
|
||
|
|
DieRecheckProcessResult processResult = _processResultManager.DieRecheckResult;
|
||
|
|
if (processResult == null || processResult.PointResults == null)
|
||
|
|
{
|
||
|
|
PointCount = 0;
|
||
|
|
FilteredPointCount = 0;
|
||
|
|
Pagination.TotalItems = 0;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach (DieRecheckPointResult pointResult in processResult.PointResults)
|
||
|
|
{
|
||
|
|
_allPointResults.Add(new DieRecheckDisplayItem
|
||
|
|
{
|
||
|
|
StepIndex = pointResult.StepIndex,
|
||
|
|
PadRow = pointResult.PadRow,
|
||
|
|
PadColumn = pointResult.PadColumn,
|
||
|
|
DieRow = pointResult.DieRow,
|
||
|
|
DieColumn = pointResult.DieColumn,
|
||
|
|
PadX = pointResult.PadX,
|
||
|
|
PadY = pointResult.PadY,
|
||
|
|
DieX = pointResult.DieX,
|
||
|
|
DieY = pointResult.DieY,
|
||
|
|
TransPathType = pointResult.TransPathType,
|
||
|
|
IsMissingBond = pointResult.IsMissingBond,
|
||
|
|
XError = pointResult.XError,
|
||
|
|
YError = pointResult.YError
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
PointCount = _allPointResults.Count;
|
||
|
|
InitializeRegion();
|
||
|
|
UpdateThresholdFlags();
|
||
|
|
Pagination.CurrentPage = 1;
|
||
|
|
ApplyFilters();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void InitializeRegion()
|
||
|
|
{
|
||
|
|
if (_allPointResults.Count == 0)
|
||
|
|
{
|
||
|
|
RecheckRegion.StartRow = 1;
|
||
|
|
RecheckRegion.StartCol = 1;
|
||
|
|
RecheckRegion.EndRow = 1;
|
||
|
|
RecheckRegion.EndCol = 1;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
RecheckRegion.StartRow = _allPointResults.Min(item => item.PadRow);
|
||
|
|
RecheckRegion.StartCol = _allPointResults.Min(item => item.PadColumn);
|
||
|
|
RecheckRegion.EndRow = Math.Max(RecheckRegion.StartRow, _allPointResults.Max(item => item.PadRow));
|
||
|
|
RecheckRegion.EndCol = Math.Max(RecheckRegion.StartCol, _allPointResults.Max(item => item.PadColumn));
|
||
|
|
}
|
||
|
|
|
||
|
|
private void UpdateThresholdFlags()
|
||
|
|
{
|
||
|
|
foreach (DieRecheckDisplayItem item in _allPointResults)
|
||
|
|
{
|
||
|
|
item.IsXThresholdExceeded = Math.Abs(item.XError) >= FilterState.XThreshold;
|
||
|
|
item.IsYThresholdExceeded = Math.Abs(item.YError) >= FilterState.YThreshold;
|
||
|
|
item.StatusSummary = BuildStatusSummary(item);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private string BuildStatusSummary(DieRecheckDisplayItem item)
|
||
|
|
{
|
||
|
|
Collection<string> tags = new Collection<string>();
|
||
|
|
if (item.IsMissingBond)
|
||
|
|
{
|
||
|
|
tags.Add(LanguageResourceHelper.GetString(MessageKey.DieRecheckStatusMissingBond));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (item.IsXThresholdExceeded)
|
||
|
|
{
|
||
|
|
tags.Add(LanguageResourceHelper.Format(MessageKey.DieRecheckStatusXExceeded, item.XError));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (item.IsYThresholdExceeded)
|
||
|
|
{
|
||
|
|
tags.Add(LanguageResourceHelper.Format(MessageKey.DieRecheckStatusYExceeded, item.YError));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (tags.Count == 0)
|
||
|
|
{
|
||
|
|
tags.Add(LanguageResourceHelper.GetString(MessageKey.DieRecheckStatusOk));
|
||
|
|
}
|
||
|
|
|
||
|
|
return string.Join(" / ", tags);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void ApplyFilters()
|
||
|
|
{
|
||
|
|
_filteredPointResults = _allPointResults.Where(MatchesFilters).ToList();
|
||
|
|
FilteredPointCount = _filteredPointResults.Count;
|
||
|
|
Pagination.TotalItems = FilteredPointCount;
|
||
|
|
|
||
|
|
if (Pagination.TotalItems == 0)
|
||
|
|
{
|
||
|
|
SelectedPointResult = null;
|
||
|
|
PointResults = new ObservableCollection<DieRecheckDisplayItem>();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (Pagination.CurrentPage > Pagination.TotalPages)
|
||
|
|
{
|
||
|
|
Pagination.CurrentPage = Pagination.TotalPages;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
LoadPagedData();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void LoadPagedData()
|
||
|
|
{
|
||
|
|
if (_filteredPointResults == null || _filteredPointResults.Count == 0)
|
||
|
|
{
|
||
|
|
PointResults = new ObservableCollection<DieRecheckDisplayItem>();
|
||
|
|
SelectedPointResult = null;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
int safePage = Math.Max(1, Math.Min(Pagination.CurrentPage, Pagination.TotalPages));
|
||
|
|
int offset = (safePage - 1) * Pagination.PageSize;
|
||
|
|
int limit = Pagination.PageSize;
|
||
|
|
|
||
|
|
PointResults = new ObservableCollection<DieRecheckDisplayItem>(_filteredPointResults.Skip(offset).Take(limit));
|
||
|
|
if (SelectedPointResult != null && !PointResults.Contains(SelectedPointResult))
|
||
|
|
{
|
||
|
|
SelectedPointResult = null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private bool MatchesFilters(DieRecheckDisplayItem item)
|
||
|
|
{
|
||
|
|
if (item == null)
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool isInRegion = item.PadRow >= RecheckRegion.StartRow
|
||
|
|
&& item.PadRow <= RecheckRegion.EndRow
|
||
|
|
&& item.PadColumn >= RecheckRegion.StartCol
|
||
|
|
&& item.PadColumn <= RecheckRegion.EndCol;
|
||
|
|
if (!isInRegion)
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (FilterState.IsMissingBondRuleSelected && !item.IsMissingBond)
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (FilterState.IsXYThresholdRuleSelected && !(item.IsXThresholdExceeded && item.IsYThresholdExceeded))
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (FilterState.IsXThresholdRuleSelected && !item.IsXThresholdExceeded)
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (FilterState.IsYThresholdRuleSelected && !item.IsYThresholdExceeded)
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|