Иногда мы не понимаем как работает регулярное выражение, которое мы составили, и хотим проверить. Есть множество восхитительных приложений встроенных в различные среды или онлайн. Мне захотелось добавить еще одно к этому списку.
В данной статье мы посмотрим, как можно обернуть Regex в кроссплатформенную графику и получить простенькое приложение для теста регулярных выражений.

Для того, чтобы создать проект с использованием avalonia ui нужно установить шаблоны с GitHub.
И создать проект из шаблона mvvm.
Для создания основного окна разместим все компоненты внутри грида.
Наше приложение состоит из 2‑х частей: верхнего аналога тулбара и рабочей области.

Тут у нас поле для ввода регулярного выражения, чекбокс, показывающий, как анализировать текст (построчно или как целый фрагмент) и кнопка справки.
В качестве контейнера выступает Док панель. Данный контрол позволяет легко заполнить контейнер элементами, прижимая их к разным сторонам и гарантируя отсутствие свободного места внутри.
И заполняем ее полем для ввода текста:
Здесь стоит отметить приятную мелочь для Avalonia ui — наличие watermark у текстовых полей.
Добавим на панель чекбокс, имеющий 2 состояния, о чем говорит IsThreeState=«False»:
И кнопку, отвечающую за вызов справки:
Основная часть
Рабочая часть будет помещена в грид:
Поле ввода представлено текст боксом:
Сплиттер позволяет подобрать удобную визуализацию под свои нужды:
А поле, отвечающее за отображение результата применения регулярных выражений поместим в бордер так как текст блок не обладает собственной рамкой:
Окно справки

для создания нового окна обратимся к терминалу
Данное окно будет содержать лишь справочную информацию и больше ничего, так что, проигнорировав контейнеры, сделаем лист бокс дочерним элементом для данного окна:
И заполним его одинаковыми элементами по мере необходимости:
Разметка достаточно простая: стек панель с 2 полями, единственное что здесь стоит отметить — атрибут Classes, что позволит стилизовать наши окна наподобие css (еще одна приятная фишка Авалонии.
И собственно покрасим сами правила в зеленый цвет:
В первую очередь озаботимся полями для всех элементов разметки:
Создадим методы, которые вернут результаты матчинга с исходным тесктом:
И с исходным текстом по линиям, для чего применим Split
И добавим метод, отображающий окно справки
Свойства и биндинги
Интересной особенностью Авалонии является возможность прибиндить метод напрямую к кнопке:
Чем мы и воспользуемся.
Для остальных полей мы просто прибиндимся к свойствам. Здесь также интересной особенностью является то, что в авалонии обновление привязки происходит при изменении содержимого контрола, что в впф делалось так: UpdateSourceTrigger=PropertyChanged в авалонии работает по умолчанию.
А так как шаблон mvvm авалонии связан с Reactive UI, то и свойства создаются с использованием данной библиотеки:
В заключение
Я надеюсь, что данная статья заинтересует не только тех, кто захочет использовать мой материал и\или как-то улучшить его, но и всех тех, кто знакомится с авалонией или ищет возможности создания кроссплатформенных приложений на c#.
Исходный код (тык).
Хотелось бы сказать спасибо ForNeVeR kekekeks worldbeater
И отметить, что поддержку по c# можно найти тут, а по авалонии вот тут.
В данной статье мы посмотрим, как можно обернуть 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# можно найти тут, а по авалонии вот тут.
