UI: Fixed crashes that could occur when using undo after typing in a text box

This commit is contained in:
Sour 2024-11-08 15:45:32 +09:00
parent 25825df619
commit 28b75c2510
20 changed files with 73 additions and 25 deletions

View file

@ -31,6 +31,8 @@
<l:EnumConverter x:Key="Enum" />
<u:FontNameConverter x:Key="FontNameConverter" />
<u:NullTextConverter x:Key="NullTextConverter" />
<VisualBrush x:Key="ViewerBgBrush" TileMode="Tile" Stretch="None" AlignmentX="Left" AlignmentY="Top" SourceRect="0,0,5,5" DestinationRect="0,0,5,5">
<VisualBrush.Visual>
<Panel Background="#202020">

View file

@ -17,7 +17,7 @@
/>
<DockPanel IsVisible="{Binding Editable}">
<Button MinWidth="30" DockPanel.Dock="Right" Content="..." Click="btnBrowse_OnClick" />
<TextBox Text="{Binding Path}" />
<TextBox Text="{Binding Path, Converter={StaticResource NullTextConverter}}" />
</DockPanel>
</Panel>
</UserControl>

View file

@ -36,7 +36,7 @@
<TextBox
Name="txtSearch"
Width="120"
Text="{Binding SearchString}"
Text="{Binding SearchString, Converter={StaticResource NullTextConverter}}"
Classes.highlight="{Binding IsErrorVisible}"
/>
<c:IconButton Icon="Assets/PreviousArrow.png" Command="{Binding FindPrev}" />

View file

@ -86,7 +86,7 @@
AcceptsReturn="True"
TextWrapping="Wrap"
Height="NaN"
Text="{Binding Breakpoint.Condition}"
Text="{Binding Breakpoint.Condition, Converter={StaticResource NullTextConverter}}"
/>
<Image Grid.Column="1" Stretch="None" Source="/Assets/Warning.png" ToolTip.Tip="{l:Translate lblConditionError}" IsVisible="{Binding !IsConditionValid}" />

View file

@ -36,7 +36,7 @@
MinHeight="21"
MaxHeight="200"
VerticalContentAlignment="Top"
Text="{Binding Label.Comment}"
Text="{Binding Label.Comment, Converter={StaticResource NullTextConverter}}"
/>
</DockPanel>
</Window>

View file

@ -33,7 +33,7 @@
<TextBox
Name="txtSearch"
HorizontalAlignment="Stretch"
Text="{Binding SearchString, ElementName=root}"
Text="{Binding SearchString, ElementName=root, Converter={StaticResource NullTextConverter}}"
/>
</DockPanel>
<CheckBox IsChecked="{Binding MatchCase, ElementName=root}" Content="{l:Translate chkMatchCase}" />

View file

@ -63,7 +63,7 @@
Grid.Column="1"
Name="txtSearch"
HorizontalAlignment="Stretch"
Text="{Binding SearchString}"
Text="{Binding SearchString, Converter={StaticResource NullTextConverter}}"
MaxLength="300"
/>
</Grid>

View file

@ -41,7 +41,7 @@
<TextBox
Name="txtAddress"
HorizontalAlignment="Stretch"
Text="{Binding Address, ElementName=root}"
Text="{Binding Address, ElementName=root, Converter={StaticResource NullTextConverter}}"
/>
</DockPanel>
</DockPanel>

View file

@ -57,7 +57,7 @@
<TextBox
Grid.Column="1" Grid.Row="2"
Name="txtLabel"
Text="{Binding Label.Label}"
Text="{Binding Label.Label, Converter={StaticResource NullTextConverter}}"
/>
<TextBlock Grid.Column="0" Grid.Row="3" Text="{l:Translate lblComment}" />
@ -68,7 +68,7 @@
Height="NaN"
MinHeight="100"
VerticalContentAlignment="Top"
Text="{Binding Label.Comment}"
Text="{Binding Label.Comment, Converter={StaticResource NullTextConverter}}"
FontFamily="{DynamicResource MesenMonospaceFont}"
FontSize="{DynamicResource MesenMonospaceFontSize}"
/>

View file

@ -75,7 +75,7 @@
ScrollViewer.VerticalScrollBarVisibility="Disabled"
Height="21"
MinHeight="21"
Text="{Binding SearchString}"
Text="{Binding SearchString, Converter={StaticResource NullTextConverter}}"
MaxLength="300"
/>
<Image

View file

@ -114,8 +114,19 @@
<Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="Auto,Auto">
<CheckBox VerticalAlignment="Center" Content="{l:Translate chkCustomFormat}" IsChecked="{Binding Options.UseCustomFormat}" />
<TextBox Grid.Column="1" Text="{Binding Format}" IsReadOnly="True" IsVisible="{Binding !Options.UseCustomFormat}" Classes="readonlyFormat" />
<TextBox Grid.Column="1" Text="{Binding Options.Format}" IsVisible="{Binding Options.UseCustomFormat}" MaxLength="1000" />
<TextBox
Grid.Column="1"
Text="{Binding Format, Converter={StaticResource NullTextConverter}}"
IsReadOnly="True"
IsVisible="{Binding !Options.UseCustomFormat}"
Classes="readonlyFormat"
/>
<TextBox
Grid.Column="1"
Text="{Binding Options.Format, Converter={StaticResource NullTextConverter}}"
IsVisible="{Binding Options.UseCustomFormat}"
MaxLength="1000"
/>
<Image Grid.Row="0" Grid.Column="2" Source="/Assets/Help.png" ToolTip.Tip="{Binding FormatTooltip}" ToolTip.Placement="Right" ToolTip.ShowDelay="0" />
<TextBlock VerticalAlignment="Center" Grid.Row="1" Text="{l:Translate lblCondition}" />
@ -137,7 +148,10 @@
ToolTip.Placement="Right"
ToolTip.ShowDelay="0"
/>
<TextBox Text="{Binding Options.Condition}" MaxLength="1000" />
<TextBox
Text="{Binding Options.Condition, Converter={StaticResource NullTextConverter}}"
MaxLength="1000"
/>
</DockPanel>
</Grid>
</StackPanel>

View file

@ -42,5 +42,7 @@
<Setter Property="Height" Value="16" />
<Setter Property="MinHeight" Value="16" />
<Setter Property="IsUndoEnabled" Value="False" />
</Style>
</Styles>

View file

@ -0,0 +1,30 @@
using Avalonia.Controls;
using Avalonia.Data.Converters;
using System;
namespace Mesen.Utilities;
/// <summary>
/// Used to fix an issue with undo in Avalonia's TextBox.
/// Typing a string, then undoing multiple times will eventually set
/// the string to null instead of an empty string, causing crashes
/// in code that does not expect the string to ever be null.
/// </summary>
public class NullTextConverter : IValueConverter
{
public object Convert(object? value, Type targetType, object? parameter, System.Globalization.CultureInfo culture)
{
if(value is string val) {
return val ?? "";
}
return "";
}
public object ConvertBack(object? value, Type targetType, object? parameter, System.Globalization.CultureInfo culture)
{
if(value is string s) {
return s;
}
return "";
}
}

View file

@ -24,7 +24,7 @@
<DockPanel>
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto" DockPanel.Dock="Top">
<TextBlock Text="{l:Translate lblSearch}" />
<TextBox Grid.Column="1" Text="{Binding SearchString}" Name="Search" />
<TextBox Grid.Column="1" Text="{Binding SearchString, Converter={StaticResource NullTextConverter}}" Name="Search" />
</Grid>
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal" DockPanel.Dock="Bottom" Margin="0 0 1 1">

View file

@ -20,7 +20,7 @@
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto,Auto,*,Auto">
<TextBlock Text="{l:Translate lblDescription}" VerticalAlignment="Center" />
<TextBox Grid.Column="1" Text="{Binding Cheat.Description}" />
<TextBox Grid.Column="1" Text="{Binding Cheat.Description, Converter={StaticResource NullTextConverter}}" />
<CheckBox
Grid.Row="1"
@ -47,7 +47,7 @@
AcceptsReturn="True"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
Height="NaN"
Text="{Binding Cheat.Codes}"
Text="{Binding Cheat.Codes, Converter={StaticResource NullTextConverter}}"
/>
<TextBox

View file

@ -25,7 +25,7 @@
<TextBox
Name="txtBarcode"
HorizontalAlignment="Stretch"
Text="{Binding Barcode, ElementName=root}"
Text="{Binding Barcode, ElementName=root, Converter={StaticResource NullTextConverter}}"
MaxLength="13"
/>
</DockPanel>

View file

@ -41,7 +41,7 @@
Margin="0 14 0 3"
/>
<TextBlock Grid.Row="3" Text="{l:Translate lblAuthor}" />
<TextBox Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding Config.Author}" />
<TextBox Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding Config.Author, Converter={StaticResource NullTextConverter}}" />
<TextBlock Grid.Row="4" Text="{l:Translate lblDescription}" />
<TextBox
@ -53,7 +53,7 @@
VerticalContentAlignment="Top"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
Text="{Binding Config.Description}"
Text="{Binding Config.Description, Converter={StaticResource NullTextConverter}}"
/>
</Grid>
</DockPanel>

View file

@ -23,13 +23,13 @@
<Grid ColumnDefinitions="Auto,1*" RowDefinitions="Auto,Auto,Auto">
<TextBlock Text="{l:Translate lblHost}" />
<TextBox Grid.Column="1" Text="{Binding Host}" />
<TextBox Grid.Column="1" Text="{Binding Host, Converter={StaticResource NullTextConverter}}" />
<TextBlock Grid.Row="1" Text="{l:Translate lblPort}" />
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Port}" />
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Port, Converter={StaticResource NullTextConverter}}" />
<TextBlock Grid.Row="2" Text="{l:Translate lblPassword}" />
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Password}" />
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Password, Converter={StaticResource NullTextConverter}}" />
</Grid>
</DockPanel>
</Window>

View file

@ -23,10 +23,10 @@
<Grid ColumnDefinitions="Auto,1*,Auto" RowDefinitions="Auto,Auto,Auto,Auto,Auto">
<TextBlock Text="{l:Translate lblPort}" />
<TextBox Grid.Column="1" Text="{Binding ServerPort}" />
<TextBox Grid.Column="1" Text="{Binding ServerPort, Converter={StaticResource NullTextConverter}}" />
<TextBlock Grid.Row="1" Text="{l:Translate lblPassword}" />
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding ServerPassword}" />
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding ServerPassword, Converter={StaticResource NullTextConverter}}" />
</Grid>
</DockPanel>
</Window>

View file

@ -15,7 +15,7 @@
<DockPanel HorizontalAlignment="Stretch">
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto" DockPanel.Dock="Top">
<TextBlock Text="{l:Translate lblSearch}" />
<TextBox Grid.Column="1" Text="{Binding SearchString}" Name="Search" />
<TextBox Grid.Column="1" Text="{Binding SearchString, Converter={StaticResource NullTextConverter}}" Name="Search" />
</Grid>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Horizontal" DockPanel.Dock="Bottom">