Иногда мы не понимаем как работает регулярное выражение, которое мы составили, и хотим проверить. Есть множество восхитительных приложений встроенных в различные среды или онлайн. Мне захотелось добавить еще одно к этому списку.
В данной статье мы посмотрим, как можно обернуть Regex в кроссплатформенную графику и получить простенькое приложение для теста регулярных выражений.
Начало
Для того, чтобы создать проект с использованием avalonia ui нужно установить шаблоны с GitHub.
И создать проект из шаблона mvvm.
dotnet new avalonia.mvvm -o MyApp
Дизайн и разметка
Для создания основного окна разместим все компоненты внутри грида.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="5" />
<RowDefinition Height="Auto" />
<RowDefinition Height="5" />
<RowDefinition Height="*" />
<RowDefinition Height="5" />
</Grid.RowDefinitions>
</Grid>
Наше приложение состоит из 2‑х частей: верхнего аналога тулбара и рабочей области.
Рассмотрим верхнюю часть
Тут у нас поле для ввода регулярного выражения, чекбокс, показывающий, как анализировать текст (построчно или как целый фрагмент) и кнопка справки.
В качестве контейнера выступает Док панель. Данный контрол позволяет легко заполнить контейнер элементами, прижимая их к разным сторонам и гарантируя отсутствие свободного места внутри.
<DockPanel Grid.Row="1">
И заполняем ее полем для ввода текста:
<TextBox Margin="5, 0, 5, 0" Watermark="Your regexp" AcceptsReturn="False" Text="{Binding RegText}"/>
Здесь стоит отметить приятную мелочь для Avalonia ui — наличие watermark у текстовых полей.
Добавим на панель чекбокс, имеющий 2 состояния, о чем говорит IsThreeState=«False»:
<CheckBox DockPanel.Dock="Right" Content="By row" IsThreeState="False" IsChecked="{Binding IsChecked}" ToolTip.Tip="Check for each row" />
И кнопку, отвечающую за вызов справки:
<Button DockPanel.Dock="Right" Content=" ? " Margin="5, 0, 5, 0" ToolTip.Tip="Show hints" Command="{Binding ShowHelp}" />
Основная часть
Рабочая часть будет помещена в грид:
<Grid Grid.Row="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="0.75*" />
</Grid.ColumnDefinitions>
</Grid>
Поле ввода представлено текст боксом:
<TextBox Grid.Column="0" AcceptsReturn="True" ScrollViewer.VerticalScrollBarVisibility="Auto" Text="{Binding InputText}"/>
Сплиттер позволяет подобрать удобную визуализацию под свои нужды:
<GridSplitter Grid.Column="1" />
А поле, отвечающее за отображение результата применения регулярных выражений поместим в бордер так как текст блок не обладает собственной рамкой:
<Border BorderBrush="Gray" BorderThickness="1" Grid.Column="2">
<TextBlock ScrollViewer.VerticalScrollBarVisibility="Auto" Text="{Binding OutputText}" />
</Border>
Окно справки
для создания нового окна обратимся к терминалу
dotnet new avalonia.window -na MyApp -n MyNewWindow
Данное окно будет содержать лишь справочную информацию и больше ничего, так что, проигнорировав контейнеры, сделаем лист бокс дочерним элементом для данного окна:
<ListBox ScrollViewer.VerticalScrollBarVisibility="Visible" VirtualizationMode="None">
</ListBox>
И заполним его одинаковыми элементами по мере необходимости:
<ListBoxItem>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="5" Text="A single character of: a, b or c" />
<TextBlock Margin="5" Classes="green" Text="[abc]" />
</StackPanel>
</ListBoxItem>
Разметка достаточно простая: стек панель с 2 полями, единственное что здесь стоит отметить — атрибут Classes, что позволит стилизовать наши окна наподобие css (еще одна приятная фишка Авалонии.
И собственно покрасим сами правила в зеленый цвет:
<Window.Styles>
<Style Selector="TextBlock.green">
<Setter Property="Foreground" Value="Green" />
</Style>
</Window.Styles>
Функциональность mvvm
В первую очередь озаботимся полями для всех элементов разметки:
private bool _isChecked;
private string _inputText;
private string _regText;
private string _outputText;
Создадим методы, которые вернут результаты матчинга с исходным тесктом:
private void SetNoRowResult()
{
OutputText = string.Join(Environment.NewLine,new Regex(_regText).Matches(_inputText));
}
И с исходным текстом по линиям, для чего применим Split
private void SetRowResult()
{
var r = new Regex(_regText);
var s = string.Empty;
foreach (var line in _inputText.Split( Environment.NewLine,StringSplitOptions.RemoveEmptyEntries))
{
s += $"--{Environment.NewLine}";
s+=string.Join(Environment.NewLine,r.Matches(line));
s += $"{Environment.NewLine}--{Environment.NewLine}";
}
OutputText = s;
}
И добавим метод, отображающий окно справки
public void ShowHelp()
{
new HelpWindow().Show();
}
Свойства и биндинги
Интересной особенностью Авалонии является возможность прибиндить метод напрямую к кнопке:
<Button Command="{Binding ShowHelp}" />
Чем мы и воспользуемся.
Для остальных полей мы просто прибиндимся к свойствам. Здесь также интересной особенностью является то, что в авалонии обновление привязки происходит при изменении содержимого контрола, что в впф делалось так: UpdateSourceTrigger=PropertyChanged в авалонии работает по умолчанию.
А так как шаблон mvvm авалонии связан с Reactive UI, то и свойства создаются с использованием данной библиотеки:
public string RegText
{
get => _regText;
set
{
this.RaiseAndSetIfChanged(ref _regText, value);
if(_isChecked) SetRowResult();
else SetNoRowResult();
}
}
В заключение
Я надеюсь, что данная статья заинтересует не только тех, кто захочет использовать мой материал иили как-то улучшить его, но и всех тех, кто знакомится с авалонией или ищет возможности создания кроссплатформенных приложений на c#.
Исходный код (тык).
Хотелось бы сказать спасибо ForNeVeR kekekeks worldbeater
И отметить, что поддержку по c# можно найти тут, а по авалонии вот тут.
Автор: Larymar