diff --git a/src/Avalonia.Base/Data/BindingOperations.cs b/src/Avalonia.Base/Data/BindingOperations.cs index ca148659e6..15de6c4d0d 100644 --- a/src/Avalonia.Base/Data/BindingOperations.cs +++ b/src/Avalonia.Base/Data/BindingOperations.cs @@ -65,7 +65,11 @@ namespace Avalonia.Data return Disposable.Empty; } case BindingMode.OneWayToSource: - return target.GetObservable(property).Subscribe(binding.Subject); + return Observable.CombineLatest( + binding.Observable, + target.GetObservable(property), + (_, v) => v) + .Subscribe(x => binding.Subject.OnNext(x)); default: throw new ArgumentException("Invalid binding mode."); } diff --git a/src/Avalonia.Base/Data/Core/PropertyAccessorNode.cs b/src/Avalonia.Base/Data/Core/PropertyAccessorNode.cs index a916142675..df8f46a7d7 100644 --- a/src/Avalonia.Base/Data/Core/PropertyAccessorNode.cs +++ b/src/Avalonia.Base/Data/Core/PropertyAccessorNode.cs @@ -59,8 +59,8 @@ namespace Avalonia.Data.Core $"Could not find a matching property accessor for {PropertyName}."); } - accessor.Subscribe(ValueChanged); _accessor = accessor; + accessor.Subscribe(ValueChanged); } protected override void StopListeningCore() diff --git a/tests/Avalonia.Markup.UnitTests/Data/BindingTests.cs b/tests/Avalonia.Markup.UnitTests/Data/BindingTests.cs index baa1bca76a..d19accb0ad 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/BindingTests.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/BindingTests.cs @@ -100,6 +100,28 @@ namespace Avalonia.Markup.UnitTests.Data Assert.Equal("baz", target.Text); } + [Fact] + public void OneWayToSource_Binding_Should_React_To_DataContext_Changed() + { + var target = new TextBlock { Text = "bar" }; + var binding = new Binding + { + Path = "Foo", + Mode = BindingMode.OneWayToSource, + }; + + target.Bind(TextBox.TextProperty, binding); + + var source = new Source { Foo = "foo" }; + target.DataContext = source; + + Assert.Equal("bar", source.Foo); + target.Text = "baz"; + Assert.Equal("baz", source.Foo); + source.Foo = "quz"; + Assert.Equal("baz", target.Text); + } + [Fact] public void Default_BindingMode_Should_Be_Used() { diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BindingTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BindingTests.cs index fef9dfb675..14abebcdb5 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BindingTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BindingTests.cs @@ -329,6 +329,33 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml Assert.Equal("Hello world", textBlock.Text); } - } + } + + [Fact] + public void Binding_OneWayToSource_Works() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var xaml = @" + +"; + var loader = new AvaloniaXamlLoader(); + var window = (Window)loader.Load(xaml); + var viewModel = new WindowViewModel(); + + window.DataContext = viewModel; + window.ApplyTemplate(); + + Assert.True(window.ShowInTaskbar); + Assert.True(viewModel.ShowInTaskbar); + } + } + + private class WindowViewModel + { + public bool ShowInTaskbar { get; set; } + } } }