v1.2
This commit is contained in:
115
FSI.BT.Tools/SystemTrayMenu/Business/App.cs
Normal file
115
FSI.BT.Tools/SystemTrayMenu/Business/App.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
// <copyright file="App.cs" company="PlaceholderCompany">
|
||||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
namespace FSI.BT.Tools.SystemTrayMenu
|
||||
{
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using Microsoft.Win32;
|
||||
using FSI.BT.Tools.SystemTrayMenu.Business;
|
||||
using FSI.BT.Tools.SystemTrayMenu.Helper.Updater;
|
||||
using FSI.BT.Tools.SystemTrayMenu.UserInterface;
|
||||
using FSI.BT.Tools.SystemTrayMenu.Utilities;
|
||||
using FSI.BT.Tools.Global.Utilities;
|
||||
|
||||
/// <summary>
|
||||
/// App contains the notifyicon, the taskbarform and the menus.
|
||||
/// </summary>
|
||||
internal class App : IDisposable
|
||||
{
|
||||
private readonly AppNotifyIcon menuNotifyIcon = new();
|
||||
private readonly Menus menus = new();
|
||||
private readonly TaskbarForm taskbarForm = null;
|
||||
|
||||
public App()
|
||||
{
|
||||
AppRestart.BeforeRestarting += Dispose;
|
||||
SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
|
||||
menus.LoadStarted += menuNotifyIcon.LoadingStart;
|
||||
menus.LoadStopped += menuNotifyIcon.LoadingStop;
|
||||
menuNotifyIcon.Click += MenuNotifyIcon_Click;
|
||||
menuNotifyIcon.OpenLog += Log.OpenLogFile;
|
||||
menus.MainPreload();
|
||||
|
||||
if (Global.Vars.SystemTrayMenuSettings.ShowInTaskbar)
|
||||
{
|
||||
taskbarForm = new TaskbarForm();
|
||||
taskbarForm.FormClosed += TaskbarForm_FormClosed;
|
||||
taskbarForm.Deactivate += SetStateNormal;
|
||||
taskbarForm.Resize += SetStateNormal;
|
||||
taskbarForm.Activated += TasbkarItemActivated;
|
||||
}
|
||||
|
||||
BT.Tools.Global.DllImports.NativeMethods.User32ShowInactiveTopmost(taskbarForm);
|
||||
|
||||
//if (Global.Vars.SystemTrayMenuSettings.CheckForUpdates)
|
||||
//{
|
||||
// new Thread((obj) => GitHubUpdate.ActivateNewVersionFormOrCheckForUpdates(
|
||||
// showWhenUpToDate: false))
|
||||
// .Start();
|
||||
//}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (taskbarForm?.InvokeRequired == true)
|
||||
{
|
||||
taskbarForm.Invoke(Dispose);
|
||||
}
|
||||
else
|
||||
{
|
||||
AppRestart.BeforeRestarting -= Dispose;
|
||||
SystemEvents.DisplaySettingsChanged -= SystemEvents_DisplaySettingsChanged;
|
||||
menus.LoadStarted -= menuNotifyIcon.LoadingStart;
|
||||
menus.LoadStopped -= menuNotifyIcon.LoadingStop;
|
||||
menus.Dispose();
|
||||
menuNotifyIcon.Click -= MenuNotifyIcon_Click;
|
||||
menuNotifyIcon.OpenLog -= Log.OpenLogFile;
|
||||
menuNotifyIcon.Dispose();
|
||||
if (taskbarForm != null)
|
||||
{
|
||||
taskbarForm.FormClosed -= TaskbarForm_FormClosed;
|
||||
taskbarForm.Deactivate -= SetStateNormal;
|
||||
taskbarForm.Resize -= SetStateNormal;
|
||||
taskbarForm.Activated -= TasbkarItemActivated;
|
||||
taskbarForm.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
|
||||
{
|
||||
menus.ReAdjustSizeAndLocation();
|
||||
}
|
||||
|
||||
private void MenuNotifyIcon_Click()
|
||||
{
|
||||
menus.SwitchOpenClose(true);
|
||||
}
|
||||
|
||||
private void TaskbarForm_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
Application.Exit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This ensures that next click on taskbaritem works as activate event/click event.
|
||||
/// </summary>
|
||||
private void SetStateNormal(object sender, EventArgs e)
|
||||
{
|
||||
if (Form.ActiveForm == taskbarForm)
|
||||
{
|
||||
taskbarForm.WindowState = FormWindowState.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
private void TasbkarItemActivated(object sender, EventArgs e)
|
||||
{
|
||||
SetStateNormal(sender, e);
|
||||
taskbarForm.Activate();
|
||||
taskbarForm.Focus();
|
||||
menus.SwitchOpenCloseByTaskbarItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
592
FSI.BT.Tools/SystemTrayMenu/Business/KeyboardInput.cs
Normal file
592
FSI.BT.Tools/SystemTrayMenu/Business/KeyboardInput.cs
Normal file
@@ -0,0 +1,592 @@
|
||||
// <copyright file="KeyboardInput.cs" company="PlaceholderCompany">
|
||||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace FSI.BT.Tools.SystemTrayMenu.Handler
|
||||
{
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using FSI.BT.Tools.Global.Utilities;
|
||||
using FSI.BT.Tools.SystemTrayMenu.DataClasses;
|
||||
using FSI.BT.Tools.SystemTrayMenu.Helper;
|
||||
using FSI.BT.Tools.SystemTrayMenu.Utilities;
|
||||
using Menu = SystemTrayMenu.UserInterface.Menu;
|
||||
|
||||
internal class KeyboardInput : IDisposable
|
||||
{
|
||||
private readonly Menu[] menus;
|
||||
private readonly KeyboardHook hook = new();
|
||||
|
||||
private int iRowKey = -1;
|
||||
private int iMenuKey;
|
||||
|
||||
public KeyboardInput(Menu[] menus)
|
||||
{
|
||||
this.menus = menus;
|
||||
}
|
||||
|
||||
public event Action HotKeyPressed;
|
||||
|
||||
public event Action ClosePressed;
|
||||
|
||||
public event Action<DataGridView, int> RowSelected;
|
||||
|
||||
public event Action<DataGridView, int> RowDeselected;
|
||||
|
||||
public event Action<DataGridView, int> EnterPressed;
|
||||
|
||||
public event Action Cleared;
|
||||
|
||||
public bool InUse { get; set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
hook.KeyPressed -= Hook_KeyPressed;
|
||||
hook.Dispose();
|
||||
}
|
||||
|
||||
public void RegisterHotKey()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Global.Vars.SystemTrayMenuSettings.HotKey))
|
||||
{
|
||||
try
|
||||
{
|
||||
hook.RegisterHotKey();
|
||||
hook.KeyPressed += Hook_KeyPressed;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
Log.Warn($"key:'{Global.Vars.SystemTrayMenuSettings.HotKey}'", ex);
|
||||
Global.Vars.SystemTrayMenuSettings.HotKey = string.Empty;
|
||||
//Global.Vars.SystemTrayMenuSettings.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetSelectedByKey()
|
||||
{
|
||||
iRowKey = -1;
|
||||
iMenuKey = 0;
|
||||
}
|
||||
|
||||
public void CmdKeyProcessed(object sender, Keys keys)
|
||||
{
|
||||
sender ??= menus[iMenuKey];
|
||||
|
||||
switch (keys)
|
||||
{
|
||||
case Keys.Enter:
|
||||
SelectByKey(keys);
|
||||
menus[iMenuKey]?.FocusTextBox();
|
||||
break;
|
||||
case Keys.Left:
|
||||
SelectByKey(keys);
|
||||
break;
|
||||
case Keys.Right:
|
||||
SelectByKey(keys);
|
||||
break;
|
||||
case Keys.Home:
|
||||
case Keys.End:
|
||||
case Keys.Up:
|
||||
case Keys.Down:
|
||||
case Keys.Escape:
|
||||
case Keys.Alt | Keys.F4:
|
||||
SelectByKey(keys);
|
||||
break;
|
||||
case Keys.Control | Keys.F:
|
||||
menus[iMenuKey]?.FocusTextBox();
|
||||
break;
|
||||
case Keys.Tab:
|
||||
{
|
||||
Menu currentMenu = (Menu)sender;
|
||||
int indexOfTheCurrentMenu = GetMenuIndex(currentMenu);
|
||||
int indexMax = menus.Where(m => m != null).Count() - 1;
|
||||
int indexNew = 0;
|
||||
if (indexOfTheCurrentMenu > 0)
|
||||
{
|
||||
indexNew = indexOfTheCurrentMenu - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
indexNew = indexMax;
|
||||
}
|
||||
|
||||
menus[indexNew]?.FocusTextBox();
|
||||
}
|
||||
|
||||
break;
|
||||
case Keys.Tab | Keys.Shift:
|
||||
{
|
||||
Menu currentMenu = (Menu)sender;
|
||||
int indexOfTheCurrentMenu = GetMenuIndex(currentMenu);
|
||||
int indexMax = menus.Where(m => m != null).Count() - 1;
|
||||
int indexNew = 0;
|
||||
if (indexOfTheCurrentMenu < indexMax)
|
||||
{
|
||||
indexNew = indexOfTheCurrentMenu + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
indexNew = 0;
|
||||
}
|
||||
|
||||
menus[indexNew]?.FocusTextBox();
|
||||
}
|
||||
|
||||
break;
|
||||
case Keys.Apps:
|
||||
{
|
||||
DataGridView dgv = menus[iMenuKey]?.GetDataGridView();
|
||||
|
||||
if (iRowKey > -1 &&
|
||||
dgv.Rows.Count > iRowKey)
|
||||
{
|
||||
Point point = dgv.GetCellDisplayRectangle(2, iRowKey, false).Location;
|
||||
RowData trigger = (RowData)dgv.Rows[iRowKey].Cells[2].Value;
|
||||
MouseEventArgs mouseEventArgs = new(MouseButtons.Right, 1, point.X, point.Y, 0);
|
||||
trigger.MouseDown(dgv, mouseEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int GetMenuIndex(in Menu currentMenu)
|
||||
{
|
||||
int index = 0;
|
||||
foreach (Menu menuFindIndex in menus.Where(m => m != null))
|
||||
{
|
||||
if (currentMenu == menuFindIndex)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
public void SearchTextChanging()
|
||||
{
|
||||
ClearIsSelectedByKey();
|
||||
}
|
||||
|
||||
public void SearchTextChanged(Menu menu, bool isSearchStringEmpty)
|
||||
{
|
||||
DataGridView dgv = menu.GetDataGridView();
|
||||
if (isSearchStringEmpty)
|
||||
{
|
||||
ClearIsSelectedByKey();
|
||||
}
|
||||
else if (dgv.Rows.Count > 0)
|
||||
{
|
||||
Select(dgv, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearIsSelectedByKey()
|
||||
{
|
||||
ClearIsSelectedByKey(iMenuKey, iRowKey);
|
||||
}
|
||||
|
||||
public void Select(DataGridView dgv, int i, bool refreshview)
|
||||
{
|
||||
int newiMenuKey = ((Menu)dgv.TopLevelControl).Level;
|
||||
if (i != iRowKey || newiMenuKey != iMenuKey)
|
||||
{
|
||||
ClearIsSelectedByKey();
|
||||
}
|
||||
|
||||
iRowKey = i;
|
||||
iMenuKey = newiMenuKey;
|
||||
|
||||
if (dgv.Rows.Count > i)
|
||||
{
|
||||
DataGridViewRow row = dgv.Rows[i];
|
||||
RowData rowData = (RowData)row.Cells[2].Value;
|
||||
if (rowData != null)
|
||||
{
|
||||
rowData.IsSelected = true;
|
||||
}
|
||||
|
||||
if (refreshview)
|
||||
{
|
||||
row.Selected = false;
|
||||
row.Selected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Hook_KeyPressed(object sender, KeyPressedEventArgs e)
|
||||
{
|
||||
HotKeyPressed?.Invoke();
|
||||
}
|
||||
|
||||
private bool IsAnyMenuSelectedByKey(
|
||||
ref DataGridView dgv,
|
||||
ref Menu menuFromSelected,
|
||||
ref string textselected)
|
||||
{
|
||||
Menu menu = menus[iMenuKey];
|
||||
bool isStillSelected = false;
|
||||
if (menu != null &&
|
||||
iRowKey > -1)
|
||||
{
|
||||
dgv = menu.GetDataGridView();
|
||||
if (dgv.Rows.Count > iRowKey)
|
||||
{
|
||||
RowData rowData = (RowData)dgv.
|
||||
Rows[iRowKey].Cells[2].Value;
|
||||
if (rowData.IsSelected)
|
||||
{
|
||||
isStillSelected = true;
|
||||
menuFromSelected = rowData.SubMenu;
|
||||
textselected = dgv.Rows[iRowKey].
|
||||
Cells[1].Value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isStillSelected;
|
||||
}
|
||||
|
||||
private void SelectByKey(Keys keys, string keyInput = "", bool keepSelection = false)
|
||||
{
|
||||
int iRowBefore = iRowKey;
|
||||
int iMenuBefore = iMenuKey;
|
||||
|
||||
Menu menu = menus[iMenuKey];
|
||||
DataGridView dgv = null;
|
||||
DataGridView dgvBefore = null;
|
||||
Menu menuFromSelected = null;
|
||||
string textselected = string.Empty;
|
||||
bool isStillSelected = IsAnyMenuSelectedByKey(ref dgv, ref menuFromSelected, ref textselected);
|
||||
if (isStillSelected)
|
||||
{
|
||||
if (keepSelection)
|
||||
{
|
||||
// If current selection is still valid for this search then skip selecting different item
|
||||
if (textselected.StartsWith(keyInput, true, CultureInfo.InvariantCulture))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dgvBefore = dgv;
|
||||
}
|
||||
else
|
||||
{
|
||||
ResetSelectedByKey();
|
||||
menu = menus[iMenuKey];
|
||||
dgv = menu.GetDataGridView();
|
||||
}
|
||||
|
||||
bool toClear = false;
|
||||
switch (keys)
|
||||
{
|
||||
case Keys.Enter:
|
||||
if (iRowKey > -1 && dgv.Rows.Count > iRowKey)
|
||||
{
|
||||
RowData trigger = (RowData)dgv.Rows[iRowKey].Cells[2].Value;
|
||||
if (trigger.IsMenuOpen || !trigger.ContainsMenu)
|
||||
{
|
||||
trigger.MouseClick(null, out bool toCloseByMouseClick);
|
||||
trigger.DoubleClick(
|
||||
new MouseEventArgs(MouseButtons.Left, 0, 0, 0, 0),
|
||||
out bool toCloseByDoubleClick);
|
||||
if (toCloseByMouseClick || toCloseByDoubleClick)
|
||||
{
|
||||
ClosePressed?.Invoke();
|
||||
}
|
||||
|
||||
if (iRowKey > -1 && dgv.Rows.Count > iRowKey)
|
||||
{
|
||||
// Raise Dgv_RowPostPaint to show ProcessStarted
|
||||
dgv.InvalidateRow(iRowKey);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
EnterPressed.Invoke(dgv, iRowKey);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case Keys.Up:
|
||||
if (SelectMatchedReverse(dgv, iRowKey) ||
|
||||
SelectMatchedReverse(dgv, dgv.Rows.Count - 1))
|
||||
{
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
toClear = true;
|
||||
}
|
||||
|
||||
break;
|
||||
case Keys.Down:
|
||||
if (SelectMatched(dgv, iRowKey) ||
|
||||
SelectMatched(dgv, 0))
|
||||
{
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
toClear = true;
|
||||
}
|
||||
|
||||
break;
|
||||
case Keys.Home:
|
||||
if (SelectMatched(dgv, 0))
|
||||
{
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
toClear = true;
|
||||
}
|
||||
|
||||
break;
|
||||
case Keys.End:
|
||||
if (SelectMatchedReverse(dgv, dgv.Rows.Count - 1))
|
||||
{
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
toClear = true;
|
||||
}
|
||||
|
||||
break;
|
||||
case Keys.Left:
|
||||
bool nextMenuLocationIsLeft = menus[iMenuKey + 1] != null && menus[iMenuKey + 1].Location.X < menus[iMenuKey].Location.X;
|
||||
bool previousMenuLocationIsRight = iMenuKey > 0 && menus[iMenuKey]?.Location.X < menus[iMenuKey - 1]?.Location.X;
|
||||
if (nextMenuLocationIsLeft || previousMenuLocationIsRight)
|
||||
{
|
||||
SelectNextMenu(iRowBefore, ref dgv, dgvBefore, menuFromSelected, isStillSelected, ref toClear);
|
||||
}
|
||||
else if (iMenuKey > 0)
|
||||
{
|
||||
SelectPreviousMenu(iRowBefore, ref menu, ref dgv, dgvBefore, ref toClear);
|
||||
}
|
||||
|
||||
break;
|
||||
case Keys.Right:
|
||||
bool nextMenuLocationIsRight = menus[iMenuKey + 1]?.Location.X > menus[iMenuKey]?.Location.X;
|
||||
bool previousMenuLocationIsLeft = iMenuKey > 0 && menus[iMenuKey]?.Location.X > menus[iMenuKey - 1]?.Location.X;
|
||||
if (nextMenuLocationIsRight || previousMenuLocationIsLeft)
|
||||
{
|
||||
SelectNextMenu(iRowBefore, ref dgv, dgvBefore, menuFromSelected, isStillSelected, ref toClear);
|
||||
}
|
||||
else if (iMenuKey > 0)
|
||||
{
|
||||
SelectPreviousMenu(iRowBefore, ref menu, ref dgv, dgvBefore, ref toClear);
|
||||
}
|
||||
|
||||
break;
|
||||
case Keys.Escape:
|
||||
case Keys.Alt | Keys.F4:
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
iMenuKey = 0;
|
||||
iRowKey = -1;
|
||||
toClear = true;
|
||||
ClosePressed?.Invoke();
|
||||
break;
|
||||
default:
|
||||
if (!string.IsNullOrEmpty(keyInput))
|
||||
{
|
||||
if (SelectMatched(dgv, iRowKey, keyInput) ||
|
||||
SelectMatched(dgv, 0, keyInput))
|
||||
{
|
||||
RowDeselected(null, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
toClear = true;
|
||||
}
|
||||
else if (isStillSelected)
|
||||
{
|
||||
iRowKey = iRowBefore - 1;
|
||||
if (SelectMatched(dgv, iRowKey, keyInput) ||
|
||||
SelectMatched(dgv, 0, keyInput))
|
||||
{
|
||||
RowDeselected(null, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
iRowKey = iRowBefore;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (isStillSelected && toClear)
|
||||
{
|
||||
ClearIsSelectedByKey(iMenuBefore, iRowBefore);
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectPreviousMenu(int iRowBefore, ref Menu menu, ref DataGridView dgv, DataGridView dgvBefore, ref bool toClear)
|
||||
{
|
||||
if (iMenuKey > 0)
|
||||
{
|
||||
if (menus[iMenuKey - 1] != null)
|
||||
{
|
||||
iMenuKey -= 1;
|
||||
iRowKey = -1;
|
||||
menu = menus[iMenuKey];
|
||||
dgv = menu.GetDataGridView();
|
||||
if (SelectMatched(dgv, dgv.SelectedRows[0].Index) ||
|
||||
SelectMatched(dgv, 0))
|
||||
{
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
toClear = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
iMenuKey = 0;
|
||||
iRowKey = -1;
|
||||
toClear = true;
|
||||
Cleared?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectNextMenu(int iRowBefore, ref DataGridView dgv, DataGridView dgvBefore, Menu menuFromSelected, bool isStillSelected, ref bool toClear)
|
||||
{
|
||||
int iMenuKeyNext = iMenuKey + 1;
|
||||
if (isStillSelected)
|
||||
{
|
||||
if (menuFromSelected != null &&
|
||||
menuFromSelected == menus[iMenuKeyNext])
|
||||
{
|
||||
dgv = menuFromSelected.GetDataGridView();
|
||||
if (dgv.Rows.Count > 0)
|
||||
{
|
||||
iMenuKey += 1;
|
||||
iRowKey = -1;
|
||||
if (SelectMatched(dgv, iRowKey) ||
|
||||
SelectMatched(dgv, 0))
|
||||
{
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
toClear = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iRowKey = -1;
|
||||
iMenuKey = menus.Where(m => m != null).Count() - 1;
|
||||
if (menus[iMenuKey] != null)
|
||||
{
|
||||
dgv = menus[iMenuKey].GetDataGridView();
|
||||
if (SelectMatched(dgv, iRowKey) ||
|
||||
SelectMatched(dgv, 0))
|
||||
{
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
toClear = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectRow(DataGridView dgv, int iRowKey)
|
||||
{
|
||||
InUse = true;
|
||||
RowSelected(dgv, iRowKey);
|
||||
}
|
||||
|
||||
private bool SelectMatched(DataGridView dgv, int indexStart, string keyInput = "")
|
||||
{
|
||||
bool found = false;
|
||||
for (int i = indexStart; i < dgv.Rows.Count; i++)
|
||||
{
|
||||
if (Select(dgv, i, keyInput))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private bool SelectMatchedReverse(DataGridView dgv, int indexStart, string keyInput = "")
|
||||
{
|
||||
bool found = false;
|
||||
for (int i = indexStart; i > -1; i--)
|
||||
{
|
||||
if (Select(dgv, i, keyInput))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private bool Select(DataGridView dgv, int i, string keyInput = "")
|
||||
{
|
||||
bool found = false;
|
||||
if (i > -1 &&
|
||||
i != iRowKey &&
|
||||
dgv.Rows.Count > i)
|
||||
{
|
||||
DataGridViewRow row = dgv.Rows[i];
|
||||
RowData rowData = (RowData)row.Cells[2].Value;
|
||||
string text = row.Cells[1].Value.ToString();
|
||||
if (text.StartsWith(keyInput, true, CultureInfo.InvariantCulture))
|
||||
{
|
||||
iRowKey = rowData.RowIndex;
|
||||
rowData.IsSelected = true;
|
||||
row.Selected = false;
|
||||
row.Selected = true;
|
||||
if (row.Index < dgv.FirstDisplayedScrollingRowIndex)
|
||||
{
|
||||
dgv.FirstDisplayedScrollingRowIndex = row.Index;
|
||||
}
|
||||
else if (row.Index >=
|
||||
dgv.FirstDisplayedScrollingRowIndex +
|
||||
dgv.DisplayedRowCount(false))
|
||||
{
|
||||
dgv.FirstDisplayedScrollingRowIndex = row.Index -
|
||||
dgv.DisplayedRowCount(false) + 1;
|
||||
}
|
||||
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private void ClearIsSelectedByKey(int menuIndex, int rowIndex)
|
||||
{
|
||||
Menu menu = menus[menuIndex];
|
||||
if (menu != null && rowIndex > -1)
|
||||
{
|
||||
DataGridView dgv = menu.GetDataGridView();
|
||||
if (dgv.Rows.Count > rowIndex)
|
||||
{
|
||||
DataGridViewRow row = dgv.Rows[rowIndex];
|
||||
row.Selected = false;
|
||||
RowData rowData = (RowData)row.Cells[2].Value;
|
||||
if (rowData != null)
|
||||
{
|
||||
rowData.IsSelected = false;
|
||||
rowData.IsClicking = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1486
FSI.BT.Tools/SystemTrayMenu/Business/Menus.cs
Normal file
1486
FSI.BT.Tools/SystemTrayMenu/Business/Menus.cs
Normal file
File diff suppressed because it is too large
Load Diff
270
FSI.BT.Tools/SystemTrayMenu/Business/MenusHelpers.cs
Normal file
270
FSI.BT.Tools/SystemTrayMenu/Business/MenusHelpers.cs
Normal file
@@ -0,0 +1,270 @@
|
||||
// <copyright file="MenusHelpers.cs" company="PlaceholderCompany">
|
||||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace FSI.BT.Tools.SystemTrayMenu.Business
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FSI.BT.Tools.Global.Utilities;
|
||||
using FSI.BT.Tools.SystemTrayMenu.DataClasses;
|
||||
using FSI.BT.Tools.SystemTrayMenu.Helper;
|
||||
using FSI.BT.Tools.SystemTrayMenu.Utilities;
|
||||
|
||||
internal static class MenusHelpers
|
||||
{
|
||||
internal static void GetItemsForMainMenu(BackgroundWorker worker, string path, ref MenuData menuData)
|
||||
{
|
||||
menuData.IsNetworkRoot = FileLnk.IsNetworkRoot(path);
|
||||
if (menuData.IsNetworkRoot)
|
||||
{
|
||||
GetNetworkRootDirectories(path, ref menuData);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetDirectories(worker, path, ref menuData);
|
||||
GetFiles(worker, path, ref menuData);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void GetAddionalItemsForMainMenu(ref MenuData menuData)
|
||||
{
|
||||
if (menuData.Level != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var path in GetAddionalPathsForMainMenu())
|
||||
{
|
||||
GetDirectoriesAndFilesRecursive(ref menuData, path.Path, path.OnlyFiles, path.Recursive);
|
||||
}
|
||||
}
|
||||
|
||||
internal static IEnumerable<(string Path, bool Recursive, bool OnlyFiles)> GetAddionalPathsForMainMenu()
|
||||
{
|
||||
foreach (string pathAndRecursivString in Global.Vars.SystemTrayMenuSettings.PathsAddToMainMenu.Split(@"|"))
|
||||
{
|
||||
if (string.IsNullOrEmpty(pathAndRecursivString))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string pathAddForMainMenu = pathAndRecursivString.Split("recursiv:")[0].Trim();
|
||||
bool recursive = pathAndRecursivString.Split("recursiv:")[1].StartsWith("True");
|
||||
bool onlyFiles = pathAndRecursivString.Split("onlyFiles:")[1].StartsWith("True");
|
||||
yield return (Path: pathAddForMainMenu, Recursive: recursive, OnlyFiles: onlyFiles);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void ReadHiddenAndReadIcons(BackgroundWorker worker, ref MenuData menuData)
|
||||
{
|
||||
List<RowData> rowDatasToRemove = new();
|
||||
foreach (RowData rowData in menuData.RowDatas)
|
||||
{
|
||||
if (worker?.CancellationPending == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!menuData.IsNetworkRoot && FolderOptions.IsHidden(rowData))
|
||||
{
|
||||
rowDatasToRemove.Add(rowData);
|
||||
continue;
|
||||
}
|
||||
|
||||
rowData.ReadIcon(true);
|
||||
}
|
||||
|
||||
menuData.RowDatas = menuData.RowDatas.Except(rowDatasToRemove).ToList();
|
||||
}
|
||||
|
||||
internal static void CheckIfValid(ref MenuData menuData)
|
||||
{
|
||||
if (menuData.Validity == MenuDataValidity.Undefined)
|
||||
{
|
||||
if (menuData.RowDatas.Count == 0)
|
||||
{
|
||||
menuData.Validity = MenuDataValidity.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
menuData.Validity = MenuDataValidity.Valid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void SortItemsWhenValid(ref MenuData menuData)
|
||||
{
|
||||
if (menuData.Validity != MenuDataValidity.Valid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
menuData.RowDatas = SortItems(menuData.RowDatas);
|
||||
}
|
||||
|
||||
internal static List<RowData> SortItems(List<RowData> rowDatas)
|
||||
{
|
||||
if (Global.Vars.SystemTrayMenuSettings.SortByTypeAndNameWindowsExplorerSort)
|
||||
{
|
||||
rowDatas = rowDatas.OrderByDescending(x => x.IsFolder)
|
||||
.ThenBy(x => x.Text, new WindowsExplorerSort()).ToList();
|
||||
}
|
||||
else if (Global.Vars.SystemTrayMenuSettings.SortByTypeAndDate)
|
||||
{
|
||||
rowDatas = rowDatas.OrderByDescending(x => x.IsFolder)
|
||||
.ThenByDescending(x => x.FileInfo.LastWriteTime).ToList();
|
||||
}
|
||||
else if (Global.Vars.SystemTrayMenuSettings.SortByFileExtensionAndName)
|
||||
{
|
||||
rowDatas = rowDatas.OrderBy(x => x.FileExtension).ThenBy(x => x.Text).ToList();
|
||||
}
|
||||
else if (Global.Vars.SystemTrayMenuSettings.SortByName)
|
||||
{
|
||||
rowDatas = rowDatas.OrderBy(x => x.Text).ToList();
|
||||
}
|
||||
else if (Global.Vars.SystemTrayMenuSettings.SortByDate)
|
||||
{
|
||||
rowDatas = rowDatas.OrderByDescending(x => x.FileInfo.LastWriteTime).ToList();
|
||||
}
|
||||
|
||||
return rowDatas;
|
||||
}
|
||||
|
||||
private static void GetNetworkRootDirectories(string path, ref MenuData menuData)
|
||||
{
|
||||
Process cmd = new();
|
||||
cmd.StartInfo.FileName = "cmd.exe";
|
||||
cmd.StartInfo.RedirectStandardInput = true;
|
||||
cmd.StartInfo.RedirectStandardOutput = true;
|
||||
cmd.StartInfo.CreateNoWindow = true;
|
||||
cmd.StartInfo.UseShellExecute = false;
|
||||
cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
|
||||
try
|
||||
{
|
||||
bool resolvedSomething = false;
|
||||
cmd.Start();
|
||||
cmd.StandardInput.WriteLine($"net view {path}");
|
||||
cmd.StandardInput.Flush();
|
||||
cmd.StandardInput.Close();
|
||||
string output = cmd.StandardOutput.ReadToEnd();
|
||||
cmd.WaitForExit();
|
||||
cmd.Close();
|
||||
List<string> lines = output
|
||||
.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
if (lines.Count > 8)
|
||||
{
|
||||
foreach (string line in lines.Skip(6).SkipLast(2))
|
||||
{
|
||||
int indexOfFirstSpace = line.IndexOf(" ", StringComparison.InvariantCulture);
|
||||
if (indexOfFirstSpace > 0)
|
||||
{
|
||||
string directory = Path.Combine(path, line[..indexOfFirstSpace]);
|
||||
menuData.RowDatas.Add(new RowData(true, false, true, menuData.Level, directory));
|
||||
resolvedSomething = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!resolvedSomething)
|
||||
{
|
||||
Log.Info($"Could not resolve network root folder: {path} , output:{output}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warn($"path:'{path}'", ex);
|
||||
if (ex is UnauthorizedAccessException)
|
||||
{
|
||||
menuData.Validity = MenuDataValidity.NoAccess;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void GetDirectories(BackgroundWorker worker, string path, ref MenuData menuData)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var directory in Directory.GetDirectories(path))
|
||||
{
|
||||
if (worker?.CancellationPending == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
menuData.RowDatas.Add(new RowData(true, false, false, menuData.Level, directory));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warn($"path:'{path}'", ex);
|
||||
if (ex is UnauthorizedAccessException)
|
||||
{
|
||||
menuData.Validity = MenuDataValidity.NoAccess;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void GetFiles(BackgroundWorker worker, string path, ref MenuData menuData)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (string file in DirectoryBySearchPattern.GetFiles(path, Config.SearchPattern))
|
||||
{
|
||||
if (worker?.CancellationPending == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
menuData.RowDatas.Add(new RowData(false, false, false, menuData.Level, file));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warn($"path:'{path}'", ex);
|
||||
if (ex is UnauthorizedAccessException)
|
||||
{
|
||||
menuData.Validity = MenuDataValidity.NoAccess;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void GetDirectoriesAndFilesRecursive(
|
||||
ref MenuData menuData,
|
||||
string path,
|
||||
bool onlyFiles,
|
||||
bool recursiv)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (string file in DirectoryBySearchPattern.GetFiles(path, Config.SearchPattern))
|
||||
{
|
||||
menuData.RowDatas.Add(new RowData(false, true, false, menuData.Level, file));
|
||||
}
|
||||
|
||||
foreach (string directory in Directory.GetDirectories(path))
|
||||
{
|
||||
if (!onlyFiles)
|
||||
{
|
||||
menuData.RowDatas.Add(new RowData(true, true, false, menuData.Level, directory));
|
||||
}
|
||||
|
||||
if (recursiv)
|
||||
{
|
||||
GetDirectoriesAndFilesRecursive(ref menuData, directory, onlyFiles, recursiv);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warn($"GetDirectoriesAndFilesRecursive path:'{path}'", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
46
FSI.BT.Tools/SystemTrayMenu/Business/WaitLeave.cs
Normal file
46
FSI.BT.Tools/SystemTrayMenu/Business/WaitLeave.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
// <copyright file="WaitLeave.cs" company="PlaceholderCompany">
|
||||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace FSI.BT.Tools.SystemTrayMenu.Handler
|
||||
{
|
||||
using System;
|
||||
using FSI.BT.Tools.SystemTrayMenu.Utilities;
|
||||
using Timer = System.Windows.Forms.Timer;
|
||||
|
||||
internal class WaitLeave : IDisposable
|
||||
{
|
||||
private readonly Timer timerLeaveCheck = new();
|
||||
|
||||
public WaitLeave(int timeUntilTriggered)
|
||||
{
|
||||
timerLeaveCheck.Interval = timeUntilTriggered;
|
||||
timerLeaveCheck.Tick += TimerLeaveCheckTick;
|
||||
}
|
||||
|
||||
public event Action LeaveTriggered;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
timerLeaveCheck.Tick -= TimerLeaveCheckTick;
|
||||
timerLeaveCheck.Dispose();
|
||||
}
|
||||
|
||||
internal void Start()
|
||||
{
|
||||
timerLeaveCheck.Stop();
|
||||
timerLeaveCheck.Start();
|
||||
}
|
||||
|
||||
internal void Stop()
|
||||
{
|
||||
timerLeaveCheck.Stop();
|
||||
}
|
||||
|
||||
internal void TimerLeaveCheckTick(object sender, EventArgs e)
|
||||
{
|
||||
timerLeaveCheck.Stop();
|
||||
LeaveTriggered?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
220
FSI.BT.Tools/SystemTrayMenu/Business/WaitToLoadMenu.cs
Normal file
220
FSI.BT.Tools/SystemTrayMenu/Business/WaitToLoadMenu.cs
Normal file
@@ -0,0 +1,220 @@
|
||||
// <copyright file="WaitToLoadMenu.cs" company="PlaceholderCompany">
|
||||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace FSI.BT.Tools.SystemTrayMenu.Handler
|
||||
{
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using FSI.BT.Tools.SystemTrayMenu.DataClasses;
|
||||
using FSI.BT.Tools.SystemTrayMenu.UserInterface;
|
||||
using FSI.BT.Tools.SystemTrayMenu.Utilities;
|
||||
using Timer = System.Windows.Forms.Timer;
|
||||
|
||||
internal class WaitToLoadMenu : IDisposable
|
||||
{
|
||||
private readonly Timer timerStartLoad = new();
|
||||
private DataGridView dgv;
|
||||
private int rowIndex;
|
||||
private DataGridView dgvTmp;
|
||||
private int rowIndexTmp;
|
||||
|
||||
private int mouseMoveEvents;
|
||||
private DateTime dateTimeLastMouseMoveEvent = DateTime.Now;
|
||||
private bool checkForMouseActive = true;
|
||||
|
||||
internal WaitToLoadMenu()
|
||||
{
|
||||
timerStartLoad.Interval = Global.Vars.SystemTrayMenuSettings.TimeUntilOpens;
|
||||
timerStartLoad.Tick += WaitStartLoad_Tick;
|
||||
}
|
||||
|
||||
internal event Action<RowData> StartLoadMenu;
|
||||
|
||||
internal event Action<int> CloseMenu;
|
||||
|
||||
internal event Action StopLoadMenu;
|
||||
|
||||
internal event Action<DataGridView, int> MouseEnterOk;
|
||||
|
||||
internal bool MouseActive { get; set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
timerStartLoad.Tick -= WaitStartLoad_Tick;
|
||||
timerStartLoad.Stop();
|
||||
timerStartLoad.Dispose();
|
||||
dgv?.Dispose();
|
||||
dgvTmp?.Dispose();
|
||||
}
|
||||
|
||||
internal void MouseEnter(object sender, DataGridViewCellEventArgs e)
|
||||
{
|
||||
if (MouseActive)
|
||||
{
|
||||
DataGridView dgv = (DataGridView)sender;
|
||||
if (dgv.Rows.Count > e.RowIndex)
|
||||
{
|
||||
MouseEnterOk(dgv, e.RowIndex);
|
||||
timerStartLoad.Stop();
|
||||
StopLoadMenu?.Invoke();
|
||||
checkForMouseActive = true;
|
||||
SetData(dgv, e.RowIndex);
|
||||
timerStartLoad.Start();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dgvTmp = (DataGridView)sender;
|
||||
rowIndexTmp = e.RowIndex;
|
||||
}
|
||||
}
|
||||
|
||||
internal void RowSelected(DataGridView dgv, int rowIndex)
|
||||
{
|
||||
if (dgv.Rows.Count > rowIndex)
|
||||
{
|
||||
timerStartLoad.Stop();
|
||||
StopLoadMenu?.Invoke();
|
||||
SetData(dgv, rowIndex);
|
||||
MouseActive = false;
|
||||
checkForMouseActive = false;
|
||||
timerStartLoad.Start();
|
||||
}
|
||||
}
|
||||
|
||||
internal void MouseLeave(object sender, DataGridViewCellEventArgs e)
|
||||
{
|
||||
if (MouseActive)
|
||||
{
|
||||
timerStartLoad.Stop();
|
||||
StopLoadMenu?.Invoke();
|
||||
ResetData((DataGridView)sender, e.RowIndex);
|
||||
}
|
||||
}
|
||||
|
||||
internal void RowDeselected(DataGridView dgv, int rowIndex)
|
||||
{
|
||||
timerStartLoad.Stop();
|
||||
StopLoadMenu?.Invoke();
|
||||
ResetData(dgv, rowIndex);
|
||||
MouseActive = false;
|
||||
}
|
||||
|
||||
internal void ClickOpensInstantly(DataGridView dgv, int rowIndex)
|
||||
{
|
||||
if (dgv.Rows.Count > rowIndex)
|
||||
{
|
||||
timerStartLoad.Stop();
|
||||
SetData(dgv, rowIndex);
|
||||
MouseActive = true;
|
||||
checkForMouseActive = false;
|
||||
CallOpenMenuNow();
|
||||
}
|
||||
}
|
||||
|
||||
internal void EnterOpensInstantly(DataGridView dgv, int rowIndex)
|
||||
{
|
||||
if (dgv.Rows.Count > rowIndex)
|
||||
{
|
||||
timerStartLoad.Stop();
|
||||
StopLoadMenu?.Invoke();
|
||||
SetData(dgv, rowIndex);
|
||||
MouseActive = false;
|
||||
checkForMouseActive = false;
|
||||
CallOpenMenuNow();
|
||||
}
|
||||
}
|
||||
|
||||
internal void MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (!MouseActive)
|
||||
{
|
||||
if (mouseMoveEvents > 6)
|
||||
{
|
||||
MouseActive = true;
|
||||
if (dgvTmp != null && !dgvTmp.IsDisposed)
|
||||
{
|
||||
MouseEnter(dgvTmp, new DataGridViewCellEventArgs(
|
||||
0, rowIndexTmp));
|
||||
}
|
||||
|
||||
mouseMoveEvents = 0;
|
||||
}
|
||||
else if (DateTime.Now - dateTimeLastMouseMoveEvent <
|
||||
new TimeSpan(0, 0, 0, 0, 200))
|
||||
{
|
||||
mouseMoveEvents++;
|
||||
}
|
||||
else
|
||||
{
|
||||
dateTimeLastMouseMoveEvent = DateTime.Now;
|
||||
mouseMoveEvents = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void WaitStartLoad_Tick(object sender, EventArgs e)
|
||||
{
|
||||
timerStartLoad.Stop();
|
||||
if (!checkForMouseActive || MouseActive)
|
||||
{
|
||||
CallOpenMenuNow();
|
||||
}
|
||||
}
|
||||
|
||||
private void CallOpenMenuNow()
|
||||
{
|
||||
if (dgv.Rows.Count > rowIndex)
|
||||
{
|
||||
RowData rowData = (RowData)dgv.Rows[rowIndex].Cells[2].Value;
|
||||
Menu menu = (Menu)dgv.FindForm();
|
||||
rowData.Level = menu.Level;
|
||||
if (rowData.ContainsMenu)
|
||||
{
|
||||
CloseMenu.Invoke(rowData.Level + 2);
|
||||
}
|
||||
|
||||
CloseMenu.Invoke(rowData.Level + 1);
|
||||
|
||||
if (!rowData.IsContextMenuOpen &&
|
||||
rowData.ContainsMenu &&
|
||||
rowData.Level + 1 < MenuDefines.MenusMax)
|
||||
{
|
||||
StartLoadMenu.Invoke(rowData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetData(DataGridView dgv, int rowIndex)
|
||||
{
|
||||
dgvTmp = null;
|
||||
this.dgv = dgv;
|
||||
this.rowIndex = rowIndex;
|
||||
RowData rowData = (RowData)dgv.Rows[rowIndex].Cells[2].Value;
|
||||
if (rowData != null)
|
||||
{
|
||||
rowData.IsSelected = true;
|
||||
}
|
||||
|
||||
dgv.Rows[rowIndex].Selected = false;
|
||||
dgv.Rows[rowIndex].Selected = true;
|
||||
}
|
||||
|
||||
private void ResetData(DataGridView dgv, int rowIndex)
|
||||
{
|
||||
if (dgv != null && dgv.Rows.Count > rowIndex)
|
||||
{
|
||||
RowData rowData = (RowData)dgv.Rows[rowIndex].Cells[2].Value;
|
||||
if (rowData != null)
|
||||
{
|
||||
rowData.IsSelected = false;
|
||||
rowData.IsClicking = false;
|
||||
dgv.Rows[rowIndex].Selected = false;
|
||||
this.dgv = null;
|
||||
this.rowIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user