header sort memory

pull/3336/head
2dust 2023-02-24 11:13:13 +08:00
parent 6f357828b7
commit 12af02435f
12 changed files with 112 additions and 97 deletions

View File

@ -1,6 +1,5 @@
using System.IO; using System.IO;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Mime; using System.Net.Mime;
using System.Text; using System.Text;
@ -26,7 +25,7 @@ namespace v2rayN.Base
if (string.IsNullOrEmpty(url)) return null; if (string.IsNullOrEmpty(url)) return null;
return await httpClient.GetStringAsync(url); return await httpClient.GetStringAsync(url);
} }
public async Task<string?> GetAsync(HttpClient client, string url, CancellationToken token = default) public async Task<string?> GetAsync(HttpClient client, string url, CancellationToken token = default)
{ {
if (string.IsNullOrWhiteSpace(url)) return null; if (string.IsNullOrWhiteSpace(url)) return null;

View File

@ -0,0 +1,10 @@
using System.Windows.Controls;
namespace v2rayN.Base
{
internal class MyDGTextColumn : DataGridTextColumn
{
public string ExName { get; set; }
}
}

View File

@ -151,9 +151,9 @@ namespace v2rayN.Handler
enableAutoAdjustMainLvColWidth = true enableAutoAdjustMainLvColWidth = true
}; };
} }
if (config.uiItem.mainLvColWidth == null) if (config.uiItem.mainColumnItem == null)
{ {
config.uiItem.mainLvColWidth = new Dictionary<string, int>(); config.uiItem.mainColumnItem = new();
} }
if (Utils.IsNullOrEmpty(config.uiItem.currentLanguage)) if (Utils.IsNullOrEmpty(config.uiItem.currentLanguage))
{ {
@ -694,7 +694,7 @@ namespace v2rayN.Handler
} }
public static int SortServers(ref Config config, string subId, EServerColName name, bool asc) public static int SortServers(ref Config config, string subId, string colName, bool asc)
{ {
var lstModel = LazyConfig.Instance.ProfileItems(subId, ""); var lstModel = LazyConfig.Instance.ProfileItems(subId, "");
if (lstModel.Count <= 0) if (lstModel.Count <= 0)
@ -720,6 +720,8 @@ namespace v2rayN.Handler
sort = t33 == null ? 0 : t33.sort sort = t33 == null ? 0 : t33.sort
}).ToList(); }).ToList();
Enum.TryParse(colName, true, out EServerColName name);
var propertyName = string.Empty; var propertyName = string.Empty;
switch (name) switch (name)
{ {
@ -730,10 +732,14 @@ namespace v2rayN.Handler
case EServerColName.security: case EServerColName.security:
case EServerColName.network: case EServerColName.network:
case EServerColName.streamSecurity: case EServerColName.streamSecurity:
case EServerColName.delay:
case EServerColName.speed:
propertyName = name.ToString(); propertyName = name.ToString();
break; break;
case EServerColName.delayVal:
propertyName = "delay";
break;
case EServerColName.speedVal:
propertyName = "speed";
break;
case EServerColName.subRemarks: case EServerColName.subRemarks:
propertyName = "subid"; propertyName = "subid";
break; break;
@ -755,7 +761,7 @@ namespace v2rayN.Handler
{ {
ProfileExHandler.Instance.SetSort(lstProfile[i].indexId, (i + 1) * 10); ProfileExHandler.Instance.SetSort(lstProfile[i].indexId, (i + 1) * 10);
} }
if (name == EServerColName.delay) if (name == EServerColName.delayVal)
{ {
var maxSort = lstProfile.Max(t => t.sort) + 10; var maxSort = lstProfile.Max(t => t.sort) + 10;
foreach (var item in lstProfile) foreach (var item in lstProfile)
@ -766,7 +772,7 @@ namespace v2rayN.Handler
} }
} }
} }
if (name == EServerColName.speed) if (name == EServerColName.speedVal)
{ {
var maxSort = lstProfile.Max(t => t.sort) + 10; var maxSort = lstProfile.Max(t => t.sort) + 10;
foreach (var item in lstProfile) foreach (var item in lstProfile)
@ -1310,44 +1316,6 @@ namespace v2rayN.Handler
} }
#endregion #endregion
#region UI
public static int AddformMainLvColWidth(ref Config config, string name, int width)
{
if (config.uiItem.mainLvColWidth == null)
{
config.uiItem.mainLvColWidth = new Dictionary<string, int>();
}
if (config.uiItem.mainLvColWidth.ContainsKey(name))
{
config.uiItem.mainLvColWidth[name] = width;
}
else
{
config.uiItem.mainLvColWidth.Add(name, width);
}
ToJsonFile(config);
return 0;
}
public static int GetformMainLvColWidth(ref Config config, string name, int width)
{
if (config.uiItem.mainLvColWidth == null)
{
config.uiItem.mainLvColWidth = new Dictionary<string, int>();
}
if (config.uiItem.mainLvColWidth.ContainsKey(name))
{
return config.uiItem.mainLvColWidth[name];
}
else
{
return width;
}
}
#endregion
#region Routing #region Routing
public static int SaveRoutingItem(ref Config config, RoutingItem item) public static int SaveRoutingItem(ref Config config, RoutingItem item)

View File

@ -274,7 +274,7 @@ namespace v2rayN.Handler
{ {
msg = string.Empty; msg = string.Empty;
ProfileItem profileItem = new(); ProfileItem profileItem = new();
try try
{ {

View File

@ -58,7 +58,7 @@ namespace v2rayN.Handler
ProfileExHandler.Instance.SetTestDelay(it.indexId, "0"); ProfileExHandler.Instance.SetTestDelay(it.indexId, "0");
break; break;
case ESpeedActionType.Speedtest: case ESpeedActionType.Speedtest:
UpdateFunc(it.indexId, "", ResUI.Speedtesting); UpdateFunc(it.indexId, "", ResUI.Speedtesting);
ProfileExHandler.Instance.SetTestSpeed(it.indexId, "0"); ProfileExHandler.Instance.SetTestSpeed(it.indexId, "0");
break; break;
case ESpeedActionType.Mixedtest: case ESpeedActionType.Mixedtest:

View File

@ -123,7 +123,8 @@ namespace v2rayN.Mode
public bool doubleClick2Activate { get; set; } public bool doubleClick2Activate { get; set; }
public bool autoHideStartup { get; set; } = true; public bool autoHideStartup { get; set; } = true;
public string mainMsgFilter { get; set; } public string mainMsgFilter { get; set; }
public Dictionary<string, int> mainLvColWidth { get; set; } public List<ColumnItem> mainColumnItem { get; set; }
} }
[Serializable] [Serializable]
@ -195,4 +196,12 @@ namespace v2rayN.Mode
public string routingIndexId { get; set; } public string routingIndexId { get; set; }
public bool enableRoutingAdvanced { get; set; } public bool enableRoutingAdvanced { get; set; }
} }
[Serializable]
public class ColumnItem
{
public string Name { get; set; }
public int Width { get; set; }
public int Index { get; set; }
}
} }

View File

@ -12,8 +12,8 @@ namespace v2rayN.Mode
network, network,
streamSecurity, streamSecurity,
subRemarks, subRemarks,
delay, delayVal,
speed, speedVal,
todayDown, todayDown,
todayUp, todayUp,

View File

@ -38,7 +38,7 @@ namespace v2rayN.ViewModels
private static Config _config; private static Config _config;
private NoticeHandler? _noticeHandler; private NoticeHandler? _noticeHandler;
private readonly PaletteHelper _paletteHelper = new(); private readonly PaletteHelper _paletteHelper = new();
private Dictionary<int, bool> _dicHeaderSort = new(); private Dictionary<string, bool> _dicHeaderSort = new();
private Action<string> _updateView; private Action<string> _updateView;
#endregion #endregion
@ -366,7 +366,7 @@ namespace v2rayN.ViewModels
}, canEditRemove); }, canEditRemove);
SortServerResultCmd = ReactiveCommand.Create(() => SortServerResultCmd = ReactiveCommand.Create(() =>
{ {
SortServer((int)EServerColName.delay); SortServer(EServerColName.delayVal.ToString());
}); });
//servers export //servers export
Export2ClientConfigCmd = ReactiveCommand.Create(() => Export2ClientConfigCmd = ReactiveCommand.Create(() =>
@ -1034,23 +1034,23 @@ namespace v2rayN.ViewModels
await DialogHost.Show(dialog, "RootDialog"); await DialogHost.Show(dialog, "RootDialog");
} }
public void SortServer(int colIndex) public void SortServer(string colName)
{ {
if (colIndex < 0) if (Utils.IsNullOrEmpty(colName))
{ {
return; return;
} }
if (!_dicHeaderSort.ContainsKey(colIndex)) if (!_dicHeaderSort.ContainsKey(colName))
{ {
_dicHeaderSort.Add(colIndex, true); _dicHeaderSort.Add(colName, true);
} }
_dicHeaderSort.TryGetValue(colIndex, out bool asc); _dicHeaderSort.TryGetValue(colName, out bool asc);
if (ConfigHandler.SortServers(ref _config, _subId, (EServerColName)colIndex, asc) != 0) if (ConfigHandler.SortServers(ref _config, _subId, colName, asc) != 0)
{ {
return; return;
} }
_dicHeaderSort[colIndex] = !asc; _dicHeaderSort[colName] = !asc;
RefreshServers(); RefreshServers();
} }

View File

@ -84,7 +84,7 @@ namespace v2rayN.ViewModels
[Reactive] public bool TunBypassMode2 { get; set; } [Reactive] public bool TunBypassMode2 { get; set; }
[Reactive] public string TunDirectIP { get; set; } [Reactive] public string TunDirectIP { get; set; }
[Reactive] public string TunDirectProcess { get; set; } [Reactive] public string TunDirectProcess { get; set; }
[Reactive] public string TunDirectDNS { get; set; } [Reactive] public string TunDirectDNS { get; set; }
[Reactive] public string TunProxyIP { get; set; } [Reactive] public string TunProxyIP { get; set; }
[Reactive] public string TunProxyProcess { get; set; } [Reactive] public string TunProxyProcess { get; set; }
[Reactive] public string TunProxyDNS { get; set; } [Reactive] public string TunProxyDNS { get; set; }

View File

@ -357,9 +357,9 @@
x:Name="txtServerFilter" x:Name="txtServerFilter"
Width="200" Width="200"
Margin="4,0" Margin="4,0"
VerticalContentAlignment="Center"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgServerTitle}" materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgServerTitle}"
materialDesign:TextFieldAssist.HasClearButton="True" materialDesign:TextFieldAssist.HasClearButton="True"
VerticalContentAlignment="Center"
Style="{StaticResource DefTextBox}" /> Style="{StaticResource DefTextBox}" />
</WrapPanel> </WrapPanel>
@ -459,6 +459,7 @@
CanUserSortColumns="False" CanUserSortColumns="False"
EnableRowVirtualization="True" EnableRowVirtualization="True"
Focusable="True" Focusable="True"
FrozenColumnCount="1"
GridLinesVisibility="All" GridLinesVisibility="All"
HeadersVisibility="All" HeadersVisibility="All"
IsReadOnly="True" IsReadOnly="True"
@ -601,41 +602,50 @@
</DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn> </DataGridTemplateColumn>
<materialDesign:DataGridTextColumn <base:MyDGTextColumn
Width="80" Width="80"
Binding="{Binding configType}" Binding="{Binding configType}"
ExName="configType"
Header="{x:Static resx:ResUI.LvServiceType}" /> Header="{x:Static resx:ResUI.LvServiceType}" />
<DataGridTextColumn <base:MyDGTextColumn
Width="150" Width="150"
Binding="{Binding remarks}" Binding="{Binding remarks}"
ExName="remarks"
Header="{x:Static resx:ResUI.LvAlias}" /> Header="{x:Static resx:ResUI.LvAlias}" />
<DataGridTextColumn <base:MyDGTextColumn
Width="120" Width="120"
Binding="{Binding address}" Binding="{Binding address}"
ExName="address"
Header="{x:Static resx:ResUI.LvAddress}" /> Header="{x:Static resx:ResUI.LvAddress}" />
<DataGridTextColumn <base:MyDGTextColumn
Width="60" Width="60"
Binding="{Binding port}" Binding="{Binding port}"
ExName="port"
Header="{x:Static resx:ResUI.LvPort}" /> Header="{x:Static resx:ResUI.LvPort}" />
<DataGridTextColumn <base:MyDGTextColumn
Width="100" Width="100"
Binding="{Binding security}" Binding="{Binding security}"
ExName="security"
Header="{x:Static resx:ResUI.LvEncryptionMethod}" /> Header="{x:Static resx:ResUI.LvEncryptionMethod}" />
<DataGridTextColumn <base:MyDGTextColumn
Width="100" Width="100"
Binding="{Binding network}" Binding="{Binding network}"
ExName="network"
Header="{x:Static resx:ResUI.LvTransportProtocol}" /> Header="{x:Static resx:ResUI.LvTransportProtocol}" />
<DataGridTextColumn <base:MyDGTextColumn
Width="100" Width="100"
Binding="{Binding streamSecurity}" Binding="{Binding streamSecurity}"
ExName="streamSecurity"
Header="{x:Static resx:ResUI.LvTLS}" /> Header="{x:Static resx:ResUI.LvTLS}" />
<DataGridTextColumn <base:MyDGTextColumn
Width="100" Width="100"
Binding="{Binding subRemarks}" Binding="{Binding subRemarks}"
ExName="subRemarks"
Header="{x:Static resx:ResUI.LvSubscription}" /> Header="{x:Static resx:ResUI.LvSubscription}" />
<DataGridTextColumn <base:MyDGTextColumn
Width="100" Width="100"
Binding="{Binding delayVal}" Binding="{Binding delayVal}"
ExName="delayVal"
Header="{x:Static resx:ResUI.LvTestDelay}"> Header="{x:Static resx:ResUI.LvTestDelay}">
<DataGridTextColumn.ElementStyle> <DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}"> <Style TargetType="{x:Type TextBlock}">
@ -643,37 +653,42 @@
<Setter Property="Foreground" Value="{Binding delay, Converter={StaticResource DelayColorConverter}}" /> <Setter Property="Foreground" Value="{Binding delay, Converter={StaticResource DelayColorConverter}}" />
</Style> </Style>
</DataGridTextColumn.ElementStyle> </DataGridTextColumn.ElementStyle>
</DataGridTextColumn> </base:MyDGTextColumn>
<DataGridTextColumn <base:MyDGTextColumn
Width="100" Width="100"
Binding="{Binding speedVal}" Binding="{Binding speedVal}"
ExName="speedVal"
Header="{x:Static resx:ResUI.LvTestSpeed}"> Header="{x:Static resx:ResUI.LvTestSpeed}">
<DataGridTextColumn.ElementStyle> <DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}"> <Style TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Right" /> <Setter Property="HorizontalAlignment" Value="Right" />
</Style> </Style>
</DataGridTextColumn.ElementStyle> </DataGridTextColumn.ElementStyle>
</DataGridTextColumn> </base:MyDGTextColumn>
<DataGridTextColumn <base:MyDGTextColumn
x:Name="colTodayUp" x:Name="colTodayUp"
Width="100" Width="100"
Binding="{Binding todayUp}" Binding="{Binding todayUp}"
ExName="todayUp"
Header="{x:Static resx:ResUI.LvTodayUploadDataAmount}" /> Header="{x:Static resx:ResUI.LvTodayUploadDataAmount}" />
<DataGridTextColumn <base:MyDGTextColumn
x:Name="colTodayDown" x:Name="colTodayDown"
Width="100" Width="100"
Binding="{Binding todayDown}" Binding="{Binding todayDown}"
ExName="todayDown"
Header="{x:Static resx:ResUI.LvTodayDownloadDataAmount}" /> Header="{x:Static resx:ResUI.LvTodayDownloadDataAmount}" />
<DataGridTextColumn <base:MyDGTextColumn
x:Name="colTotalUp" x:Name="colTotalUp"
Width="100" Width="100"
Binding="{Binding totalUp}" Binding="{Binding totalUp}"
ExName="totalUp"
Header="{x:Static resx:ResUI.LvTotalUploadDataAmount}" /> Header="{x:Static resx:ResUI.LvTotalUploadDataAmount}" />
<DataGridTextColumn <base:MyDGTextColumn
x:Name="colTotalDown" x:Name="colTotalDown"
Width="100" Width="100"
Binding="{Binding totalDown}" Binding="{Binding totalDown}"
ExName="totalDown"
Header="{x:Static resx:ResUI.LvTotalDownloadDataAmount}" /> Header="{x:Static resx:ResUI.LvTotalDownloadDataAmount}" />
</DataGrid.Columns> </DataGrid.Columns>

View File

@ -9,6 +9,7 @@ using System.Windows.Controls.Primitives;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Interop; using System.Windows.Interop;
using System.Windows.Media; using System.Windows.Media;
using v2rayN.Base;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Mode; using v2rayN.Mode;
using v2rayN.Resx; using v2rayN.Resx;
@ -265,14 +266,7 @@ namespace v2rayN.Views
return; return;
} }
//find index if (colHeader.Column.GetType().Name != typeof(MyDGTextColumn).Name)
var index = lstProfiles.Columns.IndexOf(colHeader.Column);
if (index < 0)
{
index = colHeader.TabIndex;
}
if (index == 0)
{ {
foreach (var it in lstProfiles.Columns) foreach (var it in lstProfiles.Columns)
{ {
@ -282,7 +276,8 @@ namespace v2rayN.Views
return; return;
} }
ViewModel?.SortServer(index); var colName = ((MyDGTextColumn)colHeader.Column).ExName;
ViewModel?.SortServer(colName);
} }
private void menuSelectAll_Click(object sender, RoutedEventArgs e) private void menuSelectAll_Click(object sender, RoutedEventArgs e)
@ -403,7 +398,7 @@ namespace v2rayN.Views
} }
#endregion #endregion
#region UI #region UI
private void RestoreUI() private void RestoreUI()
{ {
@ -429,11 +424,21 @@ namespace v2rayN.Views
gridMain.RowDefinitions[2].Height = new GridLength(_config.uiItem.mainGirdHeight2, GridUnitType.Star); gridMain.RowDefinitions[2].Height = new GridLength(_config.uiItem.mainGirdHeight2, GridUnitType.Star);
} }
for (int k = 0; k < lstProfiles.Columns.Count; k++) var lvColumnItem = _config.uiItem.mainColumnItem.OrderBy(t => t.Index).ToList();
for (int i = 0; i < lvColumnItem.Count; i++)
{ {
var width = ConfigHandler.GetformMainLvColWidth(ref _config, ((EServerColName)k).ToString(), Convert.ToInt32(lstProfiles.Columns[k].Width.Value)); var item = lvColumnItem[i];
lstProfiles.Columns[k].Width = width; for (int k = 1; k < lstProfiles.Columns.Count; k++)
{
var item2 = (MyDGTextColumn)lstProfiles.Columns[k];
if (item2.ExName == item.Name)
{
item2.Width = item.Width;
item2.DisplayIndex = i + 1;
}
}
} }
if (!_config.guiItem.enableStatistics) if (!_config.guiItem.enableStatistics)
{ {
colTodayUp.Visibility = Visibility.Hidden; colTodayUp.Visibility = Visibility.Hidden;
@ -447,10 +452,19 @@ namespace v2rayN.Views
_config.uiItem.mainWidth = this.Width; _config.uiItem.mainWidth = this.Width;
_config.uiItem.mainHeight = this.Height; _config.uiItem.mainHeight = this.Height;
for (int k = 0; k < lstProfiles.Columns.Count; k++) List<ColumnItem> lvColumnItem = new();
for (int k = 1; k < lstProfiles.Columns.Count; k++)
{ {
ConfigHandler.AddformMainLvColWidth(ref _config, ((EServerColName)k).ToString(), Convert.ToInt32(lstProfiles.Columns[k].ActualWidth)); var item2 = (MyDGTextColumn)lstProfiles.Columns[k];
lvColumnItem.Add(new()
{
Name = item2.ExName,
Width = Convert.ToInt32(item2.ActualWidth),
Index = item2.DisplayIndex
});
} }
_config.uiItem.mainColumnItem = lvColumnItem;
_config.uiItem.mainGirdHeight1 = Math.Ceiling(gridMain.RowDefinitions[0].ActualHeight + 0.1); _config.uiItem.mainGirdHeight1 = Math.Ceiling(gridMain.RowDefinitions[0].ActualHeight + 0.1);
_config.uiItem.mainGirdHeight2 = Math.Ceiling(gridMain.RowDefinitions[2].ActualHeight + 0.1); _config.uiItem.mainGirdHeight2 = Math.Ceiling(gridMain.RowDefinitions[2].ActualHeight + 0.1);
} }
@ -573,4 +587,4 @@ namespace v2rayN.Views
} }
} }

View File

@ -46,7 +46,7 @@ namespace v2rayN.Views
{ {
return; return;
} }
var MsgFilter = cmbMsgFilter.Text.TrimEx(); var MsgFilter = cmbMsgFilter.Text.TrimEx();
if (MsgFilter != lastMsgFilter) lastMsgFilterNotAvailable = false; if (MsgFilter != lastMsgFilter) lastMsgFilterNotAvailable = false;
if (!string.IsNullOrEmpty(MsgFilter) && !lastMsgFilterNotAvailable) if (!string.IsNullOrEmpty(MsgFilter) && !lastMsgFilterNotAvailable)
@ -64,7 +64,7 @@ namespace v2rayN.Views
} }
} }
lastMsgFilter = MsgFilter; lastMsgFilter = MsgFilter;
ShowMsg(msg); ShowMsg(msg);
} }