Browse Source

Merge branch 'master' into RemoveStyleResource

pull/1226/head
Jeremy Koritzinsky 9 years ago
committed by GitHub
parent
commit
9d51fa24be
  1. 6
      samples/ControlCatalog/SideBar.xaml
  2. 6
      samples/RenderTest/SideBar.xaml
  3. 2
      samples/VirtualizationTest/ViewModels/MainWindowViewModel.cs
  4. 4
      src/Avalonia.Controls/Control.cs
  5. 12
      src/Avalonia.Styling/Styling/Setter.cs
  6. 6
      src/Avalonia.Themes.Default/TabControl.xaml
  7. 8
      src/Avalonia.Themes.Default/TextBox.xaml
  8. 4
      src/Gtk/Avalonia.Gtk3/Interop/Native.cs
  9. 1
      src/Gtk/Avalonia.Gtk3/PopupImpl.cs
  10. 36
      src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs
  11. 2
      src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
  12. 25
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticExtension.cs
  13. 23
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/TypeExtension.cs
  14. 2
      src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs
  15. 2
      src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github
  16. 7
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs
  17. 9
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/DataTemplateTests.cs
  18. 37
      tests/Avalonia.Styling.UnitTests/SetterTests.cs

6
samples/ControlCatalog/SideBar.xaml

@ -1,11 +1,11 @@
<Styles xmlns="https://github.com/avaloniaui"> <Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style Selector="TabControl.sidebar"> <Style Selector="TabControl.sidebar">
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<DockPanel> <DockPanel>
<ScrollViewer MinWidth="190" Background="{DynamicResource ThemeAccentBrush}" DockPanel.Dock="Left"> <ScrollViewer MinWidth="190" Background="{DynamicResource ThemeAccentBrush}" DockPanel.Dock="Left">
<TabStrip Name="PART_TabStrip" <TabStrip Name="PART_TabStrip"
MemberSelector="{Static TabControl.HeaderSelector}" MemberSelector="{x:Static TabControl.HeaderSelector}"
Items="{TemplateBinding Items}" Items="{TemplateBinding Items}"
SelectedIndex="{TemplateBinding Path=SelectedIndex, Mode=TwoWay}"> SelectedIndex="{TemplateBinding Path=SelectedIndex, Mode=TwoWay}">
<TabStrip.ItemsPanel> <TabStrip.ItemsPanel>
@ -17,7 +17,7 @@
</ScrollViewer> </ScrollViewer>
<Carousel Name="PART_Content" <Carousel Name="PART_Content"
Margin="8 0 0 0" Margin="8 0 0 0"
MemberSelector="{Static TabControl.ContentSelector}" MemberSelector="{x:Static TabControl.ContentSelector}"
Items="{TemplateBinding Items}" Items="{TemplateBinding Items}"
SelectedIndex="{TemplateBinding Path=SelectedIndex}" SelectedIndex="{TemplateBinding Path=SelectedIndex}"
Transition="{TemplateBinding Transition}" Transition="{TemplateBinding Transition}"

6
samples/RenderTest/SideBar.xaml

@ -1,11 +1,11 @@
<Styles xmlns="https://github.com/avaloniaui"> <Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style Selector="TabControl.sidebar"> <Style Selector="TabControl.sidebar">
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<DockPanel> <DockPanel>
<ScrollViewer MinWidth="190" Background="{DynamicResource ThemeAccentBrush}" DockPanel.Dock="Left"> <ScrollViewer MinWidth="190" Background="{DynamicResource ThemeAccentBrush}" DockPanel.Dock="Left">
<TabStrip Name="PART_TabStrip" <TabStrip Name="PART_TabStrip"
MemberSelector="{Static TabControl.HeaderSelector}" MemberSelector="{x:Static TabControl.HeaderSelector}"
Items="{TemplateBinding Items}" Items="{TemplateBinding Items}"
SelectedIndex="{TemplateBinding Path=SelectedIndex, Mode=TwoWay}"> SelectedIndex="{TemplateBinding Path=SelectedIndex, Mode=TwoWay}">
<TabStrip.ItemsPanel> <TabStrip.ItemsPanel>
@ -17,7 +17,7 @@
</ScrollViewer> </ScrollViewer>
<Carousel Name="PART_Content" <Carousel Name="PART_Content"
Margin="8 0 0 0" Margin="8 0 0 0"
MemberSelector="{Static TabControl.ContentSelector}" MemberSelector="{x:Static TabControl.ContentSelector}"
Items="{TemplateBinding Items}" Items="{TemplateBinding Items}"
SelectedIndex="{TemplateBinding Path=SelectedIndex}" SelectedIndex="{TemplateBinding Path=SelectedIndex}"
Transition="{TemplateBinding Transition}" Transition="{TemplateBinding Transition}"

2
samples/VirtualizationTest/ViewModels/MainWindowViewModel.cs

@ -17,7 +17,7 @@ namespace VirtualizationTest.ViewModels
private int _newItemIndex; private int _newItemIndex;
private IReactiveList<ItemViewModel> _items; private IReactiveList<ItemViewModel> _items;
private string _prefix = "Item"; private string _prefix = "Item";
private Orientation _orientation; private Orientation _orientation = Orientation.Vertical;
private ItemVirtualizationMode _virtualizationMode = ItemVirtualizationMode.Simple; private ItemVirtualizationMode _virtualizationMode = ItemVirtualizationMode.Simple;
public MainWindowViewModel() public MainWindowViewModel()

4
src/Avalonia.Controls/Control.cs

@ -175,9 +175,9 @@ namespace Avalonia.Controls
set set
{ {
if (value.Trim() == string.Empty) if (String.IsNullOrWhiteSpace(value))
{ {
throw new InvalidOperationException("Cannot set Name to empty string."); throw new InvalidOperationException("Cannot set Name to null or empty string.");
} }
if (_styled) if (_styled)

12
src/Avalonia.Styling/Styling/Setter.cs

@ -141,20 +141,20 @@ namespace Avalonia.Styling
{ {
var description = style?.ToString(); var description = style?.ToString();
if (sourceInstance.Subject != null) if (sourceInstance.Mode == BindingMode.TwoWay || sourceInstance.Mode == BindingMode.OneWayToSource)
{ {
var activated = new ActivatedSubject(activator, sourceInstance.Subject, description); var activated = new ActivatedSubject(activator, sourceInstance.Subject, description);
cloned = new InstancedBinding(activated, sourceInstance.Mode, BindingPriority.StyleTrigger); cloned = new InstancedBinding(activated, sourceInstance.Mode, BindingPriority.StyleTrigger);
} }
else if (sourceInstance.Observable != null) else if (sourceInstance.Mode == BindingMode.OneTime)
{ {
var activated = new ActivatedObservable(activator, sourceInstance.Observable, description); var activated = new ActivatedValue(activator, sourceInstance.Value, description);
cloned = new InstancedBinding(activated, sourceInstance.Mode, BindingPriority.StyleTrigger); cloned = new InstancedBinding(activated, BindingMode.OneWay, BindingPriority.StyleTrigger);
} }
else else
{ {
var activated = new ActivatedValue(activator, sourceInstance.Value, description); var activated = new ActivatedObservable(activator, sourceInstance.Observable ?? sourceInstance.Subject, description);
cloned = new InstancedBinding(activated, BindingMode.OneWay, BindingPriority.StyleTrigger); cloned = new InstancedBinding(activated, sourceInstance.Mode, BindingPriority.StyleTrigger);
} }
} }
else else

6
src/Avalonia.Themes.Default/TabControl.xaml

@ -1,4 +1,4 @@
<Styles xmlns="https://github.com/avaloniaui"> <Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style Selector="TabControl"> <Style Selector="TabControl">
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
@ -7,11 +7,11 @@
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}">
<DockPanel> <DockPanel>
<TabStrip Name="PART_TabStrip" <TabStrip Name="PART_TabStrip"
MemberSelector="{Static TabControl.HeaderSelector}" MemberSelector="{x:Static TabControl.HeaderSelector}"
Items="{TemplateBinding Items}" Items="{TemplateBinding Items}"
SelectedIndex="{TemplateBinding Path=SelectedIndex, Mode=TwoWay}"/> SelectedIndex="{TemplateBinding Path=SelectedIndex, Mode=TwoWay}"/>
<Carousel Name="PART_Content" <Carousel Name="PART_Content"
MemberSelector="{Static TabControl.ContentSelector}" MemberSelector="{x:Static TabControl.ContentSelector}"
Items="{TemplateBinding Items}" Items="{TemplateBinding Items}"
SelectedIndex="{TemplateBinding Path=SelectedIndex}" SelectedIndex="{TemplateBinding Path=SelectedIndex}"
Transition="{TemplateBinding Transition}" Transition="{TemplateBinding Transition}"

8
src/Avalonia.Themes.Default/TextBox.xaml

@ -1,4 +1,4 @@
<Styles xmlns="https://github.com/avaloniaui"> <Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style Selector="TextBox"> <Style Selector="TextBox">
<Setter Property="Background" Value="{DynamicResource ThemeBackgroundBrush}"/> <Setter Property="Background" Value="{DynamicResource ThemeBackgroundBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderMidBrush}"/> <Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderMidBrush}"/>
@ -18,12 +18,12 @@
Text="{TemplateBinding Watermark}" Text="{TemplateBinding Watermark}"
DockPanel.Dock="Top"> DockPanel.Dock="Top">
<TextBlock.IsVisible> <TextBlock.IsVisible>
<MultiBinding Converter="{Static BoolConverters.And}"> <MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding RelativeSource="{RelativeSource TemplatedParent}" <Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="UseFloatingWatermark"/> Path="UseFloatingWatermark"/>
<Binding RelativeSource="{RelativeSource TemplatedParent}" <Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="Text" Path="Text"
Converter="{Static StringConverters.NotNullOrEmpty}"/> Converter="{x:Static StringConverters.NotNullOrEmpty}"/>
</MultiBinding> </MultiBinding>
</TextBlock.IsVisible> </TextBlock.IsVisible>
</TextBlock> </TextBlock>
@ -44,7 +44,7 @@
<TextBlock Name="watermark" <TextBlock Name="watermark"
Opacity="0.5" Opacity="0.5"
Text="{TemplateBinding Watermark}" Text="{TemplateBinding Watermark}"
IsVisible="{TemplateBinding Path=Text, Converter={Static StringConverters.NullOrEmpty}}"/> IsVisible="{TemplateBinding Path=Text, Converter={x:Static StringConverters.NullOrEmpty}}"/>
<TextPresenter Name="PART_TextPresenter" <TextPresenter Name="PART_TextPresenter"
Text="{TemplateBinding Text, Mode=TwoWay}" Text="{TemplateBinding Text, Mode=TwoWay}"
CaretIndex="{TemplateBinding CaretIndex}" CaretIndex="{TemplateBinding CaretIndex}"

4
src/Gtk/Avalonia.Gtk3/Interop/Native.cs

@ -102,6 +102,9 @@ namespace Avalonia.Gtk3.Interop
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)]
public delegate void gdk_window_resize(IntPtr gtkWindow, int width, int height); public delegate void gdk_window_resize(IntPtr gtkWindow, int width, int height);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)]
public delegate void gdk_window_set_override_redirect(IntPtr gdkWindow, bool value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_widget_realize(GtkWidget gtkWidget); public delegate void gtk_widget_realize(GtkWidget gtkWidget);
@ -402,6 +405,7 @@ namespace Avalonia.Gtk3.Interop
public static D.gtk_window_get_size GtkWindowGetSize; public static D.gtk_window_get_size GtkWindowGetSize;
public static D.gtk_window_resize GtkWindowResize; public static D.gtk_window_resize GtkWindowResize;
public static D.gdk_window_resize GdkWindowResize; public static D.gdk_window_resize GdkWindowResize;
public static D.gdk_window_set_override_redirect GdkWindowSetOverrideRedirect;
public static D.gtk_widget_set_size_request GtkWindowSetSizeRequest; public static D.gtk_widget_set_size_request GtkWindowSetSizeRequest;
public static D.gtk_window_set_default_size GtkWindowSetDefaultSize; public static D.gtk_window_set_default_size GtkWindowSetDefaultSize;
public static D.gtk_window_get_position GtkWindowGetPosition; public static D.gtk_window_get_position GtkWindowGetPosition;

1
src/Gtk/Avalonia.Gtk3/PopupImpl.cs

@ -19,6 +19,7 @@ namespace Avalonia.Gtk3
public PopupImpl() : base(CreateWindow()) public PopupImpl() : base(CreateWindow())
{ {
OverrideRedirect = true;
} }
} }
} }

36
src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs

@ -32,6 +32,7 @@ namespace Avalonia.Gtk3
private IDeferredRenderOperation _nextRenderOperation; private IDeferredRenderOperation _nextRenderOperation;
private readonly AutoResetEvent _canSetNextOperation = new AutoResetEvent(true); private readonly AutoResetEvent _canSetNextOperation = new AutoResetEvent(true);
internal IntPtr? GdkWindowHandle; internal IntPtr? GdkWindowHandle;
private bool _overrideRedirect;
public WindowBaseImpl(GtkWindow gtkWidget) public WindowBaseImpl(GtkWindow gtkWidget)
{ {
@ -69,12 +70,15 @@ namespace Avalonia.Gtk3
private bool OnConfigured(IntPtr gtkwidget, IntPtr ev, IntPtr userdata) private bool OnConfigured(IntPtr gtkwidget, IntPtr ev, IntPtr userdata)
{ {
int w, h; int w, h;
Native.GtkWindowGetSize(GtkWidget, out w, out h); if (!OverrideRedirect)
var size = ClientSize = new Size(w, h);
if (_lastSize != size)
{ {
Resized?.Invoke(size); Native.GtkWindowGetSize(GtkWidget, out w, out h);
_lastSize = size; var size = ClientSize = new Size(w, h);
if (_lastSize != size)
{
Resized?.Invoke(size);
_lastSize = size;
}
} }
var pos = Position; var pos = Position;
if (_lastPosition != pos) if (_lastPosition != pos)
@ -406,6 +410,28 @@ namespace Avalonia.Gtk3
if (GtkWidget.IsClosed) if (GtkWidget.IsClosed)
return; return;
Native.GtkWindowResize(GtkWidget, (int)value.Width, (int)value.Height); Native.GtkWindowResize(GtkWidget, (int)value.Width, (int)value.Height);
if (OverrideRedirect)
{
var size = ClientSize = value;
if (_lastSize != size)
{
Resized?.Invoke(size);
_lastSize = size;
}
}
}
public bool OverrideRedirect
{
get => _overrideRedirect;
set
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
Native.GdkWindowSetOverrideRedirect(Native.GtkWidgetGetWindow(GtkWidget), value);
_overrideRedirect = value;
}
}
} }
public IScreenImpl Screen public IScreenImpl Screen

2
src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj

@ -74,9 +74,7 @@
<Compile Include="Data\RelativeSource.cs" /> <Compile Include="Data\RelativeSource.cs" />
<Compile Include="MarkupExtensions\BindingExtension.cs" /> <Compile Include="MarkupExtensions\BindingExtension.cs" />
<Compile Include="MarkupExtensions\RelativeSourceExtension.cs" /> <Compile Include="MarkupExtensions\RelativeSourceExtension.cs" />
<Compile Include="MarkupExtensions\StaticExtension.cs" />
<Compile Include="MarkupExtensions\TemplateBindingExtension.cs" /> <Compile Include="MarkupExtensions\TemplateBindingExtension.cs" />
<Compile Include="MarkupExtensions\TypeExtension.cs" />
<Compile Include="Parsers\SelectorGrammar.cs" /> <Compile Include="Parsers\SelectorGrammar.cs" />
<Compile Include="Parsers\SelectorParser.cs" /> <Compile Include="Parsers\SelectorParser.cs" />
<Compile Include="PortableXaml\AvaloniaTypeAttributeProvider.cs" /> <Compile Include="PortableXaml\AvaloniaTypeAttributeProvider.cs" />

25
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticExtension.cs

@ -1,25 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
namespace Avalonia.Markup.Xaml.MarkupExtensions
{
public class StaticExtension : Portable.Xaml.Markup.StaticExtension
{
public StaticExtension()
{
}
public StaticExtension(string member)
: base(member)
{
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return base.ProvideValue(serviceProvider);
}
}
}

23
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/TypeExtension.cs

@ -1,23 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
namespace Avalonia.Markup.Xaml.MarkupExtensions
{
public class TypeExtension : Portable.Xaml.Markup.TypeExtension
{
public TypeExtension()
{
}
public TypeExtension(string typeName) : base(typeName)
{
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return base.ProvideValue(serviceProvider);
}
}
}

2
src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs

@ -135,6 +135,8 @@ namespace Avalonia.Markup.Xaml.PortableXaml
}; };
} }
protected override bool LookupIsUnknown() => false;
protected override XamlType LookupType() protected override XamlType LookupType()
{ {
var propType = GetPropertyType(); var propType = GetPropertyType();

2
src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github

@ -1 +1 @@
Subproject commit eebf9dbb9275ecc48c18ec24f6fbad8cb494857f Subproject commit f226a516fe2bc191145c1fbf732f5a087f121a33

7
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs

@ -607,8 +607,8 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
public void Multi_Xaml_Binding_Is_Parsed() public void Multi_Xaml_Binding_Is_Parsed()
{ {
var xaml = var xaml =
@"<MultiBinding xmlns='https://github.com/avaloniaui' @"<MultiBinding xmlns='https://github.com/avaloniaui' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
Converter='{Static BoolConverters.And}'> Converter ='{x:Static BoolConverters.And}'>
<Binding Path='Foo' /> <Binding Path='Foo' />
<Binding Path='Bar' /> <Binding Path='Bar' />
</MultiBinding>"; </MultiBinding>";
@ -809,10 +809,11 @@ do we need it?")]
{ {
var xaml = var xaml =
@"<ContentControl xmlns='https://github.com/avaloniaui' @"<ContentControl xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.Xaml;assembly=Avalonia.Markup.Xaml.UnitTests'> xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.Xaml;assembly=Avalonia.Markup.Xaml.UnitTests'>
<ContentControl.ContentTemplate> <ContentControl.ContentTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Tag='{Static local:NonControl.StringProperty}'/> <TextBlock Tag='{x:Static local:NonControl.StringProperty}'/>
</DataTemplate> </DataTemplate>
</ContentControl.ContentTemplate> </ContentControl.ContentTemplate>
</ContentControl>"; </ContentControl>";

9
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/DataTemplateTests.cs

@ -17,9 +17,10 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
{ {
var xaml = @" var xaml = @"
<Window xmlns='https://github.com/avaloniaui' <Window xmlns='https://github.com/avaloniaui'
xmlns:sys='clr-namespace:System;assembly=mscorlib'> xmlns:sys='clr-namespace:System;assembly=mscorlib'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Window.DataTemplates> <Window.DataTemplates>
<DataTemplate DataType='{Type sys:String}'> <DataTemplate DataType='{x:Type sys:String}'>
<Canvas Name='foo'/> <Canvas Name='foo'/>
</DataTemplate> </DataTemplate>
</Window.DataTemplates> </Window.DataTemplates>
@ -43,10 +44,10 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
using (UnitTestApplication.Start(TestServices.StyledWindow)) using (UnitTestApplication.Start(TestServices.StyledWindow))
{ {
var xaml = @" var xaml = @"
<Window xmlns='https://github.com/avaloniaui' <Window xmlns='https://github.com/avaloniaui' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests;assembly=Avalonia.Markup.Xaml.UnitTests'> xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests;assembly=Avalonia.Markup.Xaml.UnitTests'>
<Window.DataTemplates> <Window.DataTemplates>
<DataTemplate DataType='{Type local:TestViewModel}'> <DataTemplate DataType='{x:Type local:TestViewModel}'>
<Canvas Name='foo' DataContext='{Binding Child}'/> <Canvas Name='foo' DataContext='{Binding Child}'/>
</DataTemplate> </DataTemplate>
</Window.DataTemplates> </Window.DataTemplates>

37
tests/Avalonia.Styling.UnitTests/SetterTests.cs

@ -8,6 +8,9 @@ using Avalonia.Data;
using Xunit; using Xunit;
using System; using System;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using Avalonia.Markup.Xaml.Data;
using Avalonia.Markup;
using System.Globalization;
namespace Avalonia.Styling.UnitTests namespace Avalonia.Styling.UnitTests
{ {
@ -61,5 +64,39 @@ namespace Avalonia.Styling.UnitTests
Assert.NotNull(NameScope.GetNameScope((Control)control.Child)); Assert.NotNull(NameScope.GetNameScope((Control)control.Child));
} }
[Fact]
public void Does_Not_Call_Converter_ConvertBack_On_OneWay_Binding()
{
var control = new Decorator { Name = "foo" };
var style = Mock.Of<IStyle>();
var binding = new Binding("Name", BindingMode.OneWay)
{
Converter = new TestConverter(),
RelativeSource = new RelativeSource(RelativeSourceMode.Self),
};
var setter = new Setter(Decorator.TagProperty, binding);
var activator = new BehaviorSubject<bool>(true);
setter.Apply(style, control, activator);
Assert.Equal("foobar", control.Tag);
// Issue #1218 caused TestConverter.ConvertBack to throw here.
activator.OnNext(false);
Assert.Null(control.Tag);
}
private class TestConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value.ToString() + "bar";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
} }
} }

Loading…
Cancel
Save