I don't know why binding to Text doesnt work in TextBox
https://github.com/pelmenstar1/test-projects/blob/master/AvaloniaBindingTest/ViewModels/MainWindowViewModel.cs
public class MainWindowViewModel : ViewModelBase
{
private string _str = "#0000";
public string String
{
get => _str;
set
{
if (value!= null && value.Length > 0 && value[0] == '#' && value.Length <= 5)
{
_str = value;
}
this.RaisePropertyChanged(nameof(String));
}
}
}
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:AvaloniaBindingTest.ViewModels;assembly=AvaloniaBindingTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaBindingTest.Views.MainWindow"
Icon="/Assets/avalonia-logo.ico"
Title="AvaloniaBindingTest">
<Design.DataContext>
<vm:MainWindowViewModel/>
</Design.DataContext>
<TextBox Text="{Binding String, Mode=TwoWay}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Window>

Where did you find a bug here?
All works as expected.
@pelmenstar1 You probably want to validate value, not _str:
if (value != null && value.Length > 0 && value[0] == '#' && value.Length <= 5)
TextBox doesnt update text, but I this.RaisePropertyChanged(nameof(String))
@jp2masa I fixed but it works the same
What are you trying to achieve? Add validation for String property?
I'm trying to do so that if String property changed then text in TextBox should be changed as I bind String to Text
So your Q is: why TextBox doesn't drop value to the previous one?
So my Q: Why text in TextBox doesn't equal String, but I bound String to Text
It seems to be a bug.
I think this happens due to _ignoreTextChanges field:
Changes that caused by setter in VM are simple ignored.
Does anybody know how to fix it?
Hmm, that line was added by https://github.com/AvaloniaUI/Avalonia/commit/a222fa9b0c2c14380db40d98dd553f2d744517f2:
Don't modify text due to binding when typing.
If a TextBox is e.g. bound to an int and the user types "02" then the
TextBox text should be "02" - not the value that comes back from the
binding which will be "2".
This was added in #691 back in 2016. However cross-checking with WPF, WPF doesn't seem to have this behavior. If a TextBox is bound to an int and the user types "02" then the textbox will display simply "2".
I think we need to double-check our binding behavior in such cases where the setter doesn't preserve the value written to it.
Is it fixable now?
And is it bug or not?
It's a difference in behavior between WPF and Avalonia at least. It needs some investigation.
In the meantime, you have a few options:
TextBox with a red outline and an error message.outside theTextBox` so the user doesn't have to enter it, e.g.<StackPanel Orientation="Horizontal">
<TextBlock>#</TextBlock>
<TextBox Text="{Binding String, Mode=TwoWay}"/>
<StackPanel>
set
{
if (!value.StartsWith("#"))
{
throw new Exception("Enter a #");
}
DispatcherTimer.RunOnce(() => this.RaiseAndSetIfChanged(ref _stringValue, value), TimeSpan.FromMilliseconds(10))
}
Repoening because this needs investigation.
Most helpful comment
Hmm, that line was added by https://github.com/AvaloniaUI/Avalonia/commit/a222fa9b0c2c14380db40d98dd553f2d744517f2:
This was added in #691 back in 2016. However cross-checking with WPF, WPF doesn't seem to have this behavior. If a
TextBoxis bound to an int and the user types "02" then the textbox will display simply "2".I think we need to double-check our binding behavior in such cases where the setter doesn't preserve the value written to it.