Update MsgView.axaml.cs Plan C (#8035)

* Add avaloniaEdit for test

* Adjust avaloniaEdit

* Optimize and improve message function

* Update build-linux.yml

* Update MsgView.axaml

* Update MsgView.axaml.cs

---------

Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
This commit is contained in:
JieXu
2025-09-26 13:55:35 +08:00
committed by GitHub
parent d86003df55
commit 21a773f400
9 changed files with 107 additions and 83 deletions

View File

@@ -11,6 +11,7 @@
RequestedThemeVariant="Default">
<Application.Styles>
<semi:SemiTheme />
<semi:AvaloniaEditSemiTheme />
<StyleInclude Source="Assets/GlobalStyles.axaml" />
<StyleInclude Source="avares://Semi.Avalonia.DataGrid/Index.axaml" />
<dialogHost:DialogHostStyles />

View File

@@ -5,6 +5,7 @@ using Avalonia.Controls.Notifications;
using Avalonia.Controls.Primitives;
using Avalonia.Media;
using Avalonia.Styling;
using AvaloniaEdit;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Semi.Avalonia;
@@ -112,7 +113,8 @@ public class ThemeSettingViewModel : MyReactiveObject
x.OfType<ContextMenu>(),
x.OfType<DataGridRow>(),
x.OfType<ListBoxItem>(),
x.OfType<HeaderedContentControl>()
x.OfType<HeaderedContentControl>(),
x.OfType<TextEditor>()
));
style.Add(new Setter()
{
@@ -153,7 +155,8 @@ public class ThemeSettingViewModel : MyReactiveObject
x.OfType<DataGridRow>(),
x.OfType<ListBoxItem>(),
x.OfType<HeaderedContentControl>(),
x.OfType<WindowNotificationManager>()
x.OfType<WindowNotificationManager>(),
x.OfType<TextEditor>()
));
style.Add(new Setter()
{

View File

@@ -2,6 +2,7 @@
x:Class="v2rayN.Desktop.Views.MsgView"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:avaloniaEdit="clr-namespace:AvaloniaEdit;assembly=AvaloniaEdit"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
@@ -70,35 +71,36 @@
Theme="{DynamicResource SimpleToggleSwitch}" />
</WrapPanel>
<ScrollViewer x:Name="msgScrollViewer" VerticalScrollBarVisibility="Auto">
<SelectableTextBlock
Name="txtMsg"
Margin="{StaticResource Margin8}"
VerticalAlignment="Stretch"
Classes="TextArea"
TextAlignment="Left"
TextWrapping="Wrap">
<SelectableTextBlock.ContextMenu>
<ContextMenu>
<MenuItem
x:Name="menuMsgViewSelectAll"
Click="menuMsgViewSelectAll_Click"
Header="{x:Static resx:ResUI.menuMsgViewSelectAll}" />
<MenuItem
x:Name="menuMsgViewCopy"
Click="menuMsgViewCopy_Click"
Header="{x:Static resx:ResUI.menuMsgViewCopy}" />
<MenuItem
x:Name="menuMsgViewCopyAll"
Click="menuMsgViewCopyAll_Click"
Header="{x:Static resx:ResUI.menuMsgViewCopyAll}" />
<MenuItem
x:Name="menuMsgViewClear"
Click="menuMsgViewClear_Click"
Header="{x:Static resx:ResUI.menuMsgViewClear}" />
</ContextMenu>
</SelectableTextBlock.ContextMenu>
</SelectableTextBlock>
</ScrollViewer>
<avaloniaEdit:TextEditor
Name="txtMsg"
Margin="{StaticResource Margin8}"
IsReadOnly="True"
VerticalScrollBarVisibility="Auto"
WordWrap="True">
<avaloniaEdit:TextEditor.Options>
<avaloniaEdit:TextEditorOptions AllowScrollBelowDocument="False"/>
</avaloniaEdit:TextEditor.Options>
<avaloniaEdit:TextEditor.ContextFlyout>
<MenuFlyout>
<MenuItem
x:Name="menuMsgViewSelectAll"
Click="menuMsgViewSelectAll_Click"
Header="{x:Static resx:ResUI.menuMsgViewSelectAll}" />
<MenuItem
x:Name="menuMsgViewCopy"
Click="menuMsgViewCopy_Click"
Header="{x:Static resx:ResUI.menuMsgViewCopy}" />
<MenuItem
x:Name="menuMsgViewCopyAll"
Click="menuMsgViewCopyAll_Click"
Header="{x:Static resx:ResUI.menuMsgViewCopyAll}" />
<MenuItem
x:Name="menuMsgViewClear"
Click="menuMsgViewClear_Click"
Header="{x:Static resx:ResUI.menuMsgViewClear}" />
</MenuFlyout>
</avaloniaEdit:TextEditor.ContextFlyout>
</avaloniaEdit:TextEditor>
</DockPanel>
</UserControl>

View File

@@ -1,5 +1,4 @@
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.ReactiveUI;
using Avalonia.Threading;
@@ -10,13 +9,12 @@ namespace v2rayN.Desktop.Views;
public partial class MsgView : ReactiveUserControl<MsgViewModel>
{
private readonly ScrollViewer _scrollViewer;
private const int MaxLines = 350;
private const int KeepLines = 320;
public MsgView()
{
InitializeComponent();
_scrollViewer = this.FindControl<ScrollViewer>("msgScrollViewer");
ViewModel = new MsgViewModel(UpdateViewHandler);
this.WhenActivated(disposables =>
@@ -34,9 +32,8 @@ public partial class MsgView : ReactiveUserControl<MsgViewModel>
if (obj is null)
return false;
Dispatcher.UIThread.Post(() =>
ShowMsg(obj),
DispatcherPriority.ApplicationIdle);
Dispatcher.UIThread.Post(() => ShowMsg(obj),
DispatcherPriority.ApplicationIdle);
break;
}
return await Task.FromResult(true);
@@ -44,23 +41,35 @@ public partial class MsgView : ReactiveUserControl<MsgViewModel>
private void ShowMsg(object msg)
{
txtMsg.Text = msg.ToString();
txtMsg.AppendText(msg.ToString());
if (txtMsg.Document.LineCount > MaxLines)
{
var lc = txtMsg.Document.LineCount;
var cutLineNumber = lc - KeepLines;
var cutLine = txtMsg.Document.GetLineByNumber(cutLineNumber);
txtMsg.Document.Remove(0, cutLine.Offset);
}
if (togScrollToEnd.IsChecked ?? true)
{
_scrollViewer?.ScrollToEnd();
txtMsg.ScrollToEnd();
}
}
public void ClearMsg()
{
ViewModel?.ClearMsg();
txtMsg.Text = "";
txtMsg.Text = string.Empty;
txtMsg.AppendText("----- Message cleared -----\n");
}
private void menuMsgViewSelectAll_Click(object? sender, RoutedEventArgs e)
{
txtMsg.Focus();
txtMsg.SelectAll();
Dispatcher.UIThread.Post(() =>
{
txtMsg.TextArea.Focus();
txtMsg.SelectAll();
}, DispatcherPriority.Render);
}
private async void menuMsgViewCopy_Click(object? sender, RoutedEventArgs e)

View File

@@ -9,6 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia.AvaloniaEdit" />
<PackageReference Include="Avalonia.Controls.DataGrid">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
@@ -17,6 +18,7 @@
<PackageReference Include="Avalonia.ReactiveUI" />
<PackageReference Include="MessageBox.Avalonia" />
<PackageReference Include="Semi.Avalonia" />
<PackageReference Include="Semi.Avalonia.AvaloniaEdit" />
<PackageReference Include="Semi.Avalonia.DataGrid">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>