diff --git a/samples/ControlCatalog/App.xaml.cs b/samples/ControlCatalog/App.xaml.cs index cb50cba540..22f4e9be1f 100644 --- a/samples/ControlCatalog/App.xaml.cs +++ b/samples/ControlCatalog/App.xaml.cs @@ -81,7 +81,7 @@ namespace ControlCatalog public override void Initialize() { - Styles.Insert(0, FluentDark); + Styles.Insert(0, FluentLight); AvaloniaXamlLoader.Load(this); } diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml index 790813fda0..bd5beafe29 100644 --- a/samples/ControlCatalog/MainView.xaml +++ b/samples/ControlCatalog/MainView.xaml @@ -77,8 +77,8 @@ Full Decorations - Fluent - Dark Fluent - Light + Fluent - Dark Simple - Light Simple - Dark diff --git a/samples/ControlCatalog/MainView.xaml.cs b/samples/ControlCatalog/MainView.xaml.cs index b0c205246e..c84f2f06b6 100644 --- a/samples/ControlCatalog/MainView.xaml.cs +++ b/samples/ControlCatalog/MainView.xaml.cs @@ -38,10 +38,10 @@ namespace ControlCatalog switch (themes.SelectedIndex) { case 0: - Application.Current.Styles[0] = App.FluentDark; + Application.Current.Styles[0] = App.FluentLight; break; case 1: - Application.Current.Styles[0] = App.FluentLight; + Application.Current.Styles[0] = App.FluentDark; break; case 2: Application.Current.Styles[0] = App.DefaultLight; diff --git a/src/Avalonia.Animation/KeySplineTypeConverter.cs b/src/Avalonia.Animation/KeySplineTypeConverter.cs index cd7427a37d..b026206e5f 100644 --- a/src/Avalonia.Animation/KeySplineTypeConverter.cs +++ b/src/Avalonia.Animation/KeySplineTypeConverter.cs @@ -19,7 +19,7 @@ namespace Avalonia.Animation public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { - return KeySpline.Parse((string)value, culture); + return KeySpline.Parse((string)value, CultureInfo.InvariantCulture); } } } diff --git a/src/Avalonia.Base/AvaloniaObject.cs b/src/Avalonia.Base/AvaloniaObject.cs index 65233f9230..6645d25b5d 100644 --- a/src/Avalonia.Base/AvaloniaObject.cs +++ b/src/Avalonia.Base/AvaloniaObject.cs @@ -113,16 +113,8 @@ namespace Avalonia /// The binding information. public IBinding this[IndexerDescriptor binding] { - get - { - return new IndexerBinding(this, binding.Property, binding.Mode); - } - - set - { - var sourceBinding = value as IBinding; - this.Bind(binding.Property, sourceBinding); - } + get { return new IndexerBinding(this, binding.Property, binding.Mode); } + set { this.Bind(binding.Property, value); } } public bool CheckAccess() => Dispatcher.UIThread.CheckAccess(); diff --git a/src/Avalonia.Base/Data/Core/Plugins/DataAnnotationsValidationPlugin.cs b/src/Avalonia.Base/Data/Core/Plugins/DataAnnotationsValidationPlugin.cs index 3b61f6d898..f052283b22 100644 --- a/src/Avalonia.Base/Data/Core/Plugins/DataAnnotationsValidationPlugin.cs +++ b/src/Avalonia.Base/Data/Core/Plugins/DataAnnotationsValidationPlugin.cs @@ -63,12 +63,12 @@ namespace Avalonia.Data.Core.Plugins { if (errors.Count == 1) { - return new ValidationException(errors[0].ErrorMessage); + return new DataValidationException(errors[0].ErrorMessage); } else { return new AggregateException( - errors.Select(x => new ValidationException(x.ErrorMessage))); + errors.Select(x => new DataValidationException(x.ErrorMessage))); } } } diff --git a/src/Avalonia.Controls.DataGrid/DataGrid.cs b/src/Avalonia.Controls.DataGrid/DataGrid.cs index 7c57ea3db9..5bb2763566 100644 --- a/src/Avalonia.Controls.DataGrid/DataGrid.cs +++ b/src/Avalonia.Controls.DataGrid/DataGrid.cs @@ -31,7 +31,7 @@ namespace Avalonia.Controls /// /// Displays data in a customizable grid. /// - [PseudoClasses(":invalid")] + [PseudoClasses(":invalid", ":empty-rows", ":empty-columns")] public partial class DataGrid : TemplatedControl { private const string DATAGRID_elementRowsPresenterName = "PART_RowsPresenter"; @@ -711,6 +711,7 @@ namespace Avalonia.Controls DisplayData = new DataGridDisplayData(this); ColumnsInternal = CreateColumnsInstance(); + ColumnsInternal.CollectionChanged += ColumnsInternal_CollectionChanged; RowHeightEstimate = DATAGRID_defaultRowHeight; RowDetailsHeightEstimate = 0; @@ -727,6 +728,8 @@ namespace Avalonia.Controls CurrentCellCoordinates = new DataGridCellCoordinates(-1, -1); RowGroupHeaderHeightEstimate = DATAGRID_defaultRowHeight; + + UpdatePseudoClasses(); } private void SetValueNoCallback(AvaloniaProperty property, T value, BindingPriority priority = BindingPriority.LocalValue) @@ -851,9 +854,27 @@ namespace Avalonia.Controls // can be set when the DataGrid is not part of the visual tree _measured = false; InvalidateMeasure(); + + UpdatePseudoClasses(); } } + private void ColumnsInternal_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.Action == NotifyCollectionChangedAction.Add + || e.Action == NotifyCollectionChangedAction.Remove + || e.Action == NotifyCollectionChangedAction.Reset) + { + UpdatePseudoClasses(); + } + } + + internal void UpdatePseudoClasses() + { + PseudoClasses.Set(":empty-columns", !ColumnsInternal.GetVisibleColumns().Any()); + PseudoClasses.Set(":empty-rows", !DataConnection.Any()); + } + private void OnSelectedIndexChanged(AvaloniaPropertyChangedEventArgs e) { if (!_areHandlersSuspended) @@ -1348,7 +1369,6 @@ namespace Avalonia.Controls internal DataGridColumnCollection ColumnsInternal { get; - private set; } internal int AnchorSlot diff --git a/src/Avalonia.Controls.DataGrid/DataGridDataConnection.cs b/src/Avalonia.Controls.DataGrid/DataGridDataConnection.cs index 19539bf032..a94acdec57 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridDataConnection.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridDataConnection.cs @@ -77,24 +77,7 @@ namespace Avalonia.Controls private set; } - public int Count - { - get - { - IList list = List; - if (list != null) - { - return list.Count; - } - - if(DataSource is DataGridCollectionView cv) - { - return cv.Count; - } - - return DataSource?.Cast().Count() ?? 0; - } - } + public int Count => GetCount(true); public bool DataIsPrimitive { @@ -210,6 +193,24 @@ namespace Avalonia.Controls } } + internal bool Any() + { + return GetCount(false) > 0; + } + + /// When "allowSlow" is false, method will not use Linq.Count() method and will return 0 or 1 instead. + private int GetCount(bool allowSlow) + { + return DataSource switch + { + ICollection collection => collection.Count, + DataGridCollectionView cv => cv.Count, + IEnumerable enumerable when allowSlow => enumerable.Cast().Count(), + IEnumerable enumerable when !allowSlow => enumerable.Cast().Any() ? 1 : 0, + _ => 0 + }; + } + /// /// Puts the entity into editing mode if possible /// @@ -675,6 +676,8 @@ namespace Avalonia.Controls } break; } + + _owner.UpdatePseudoClasses(); } private void UpdateDataProperties() diff --git a/src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml b/src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml index 30e33c2b2d..998198cc1c 100644 --- a/src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml +++ b/src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml @@ -588,18 +588,11 @@ - - + Fill="{DynamicResource DataGridGridLinesBrush}" /> + + + + diff --git a/src/Avalonia.Controls/Calendar/CalendarDatePicker.cs b/src/Avalonia.Controls/Calendar/CalendarDatePicker.cs index 046b55d49a..7c259f0a09 100644 --- a/src/Avalonia.Controls/Calendar/CalendarDatePicker.cs +++ b/src/Avalonia.Controls/Calendar/CalendarDatePicker.cs @@ -420,7 +420,7 @@ namespace Avalonia.Controls _calendar.DayButtonMouseUp -= Calendar_DayButtonMouseUp; _calendar.DisplayDateChanged -= Calendar_DisplayDateChanged; _calendar.SelectedDatesChanged -= Calendar_SelectedDatesChanged; - _calendar.PointerPressed -= Calendar_PointerPressed; + _calendar.PointerReleased -= Calendar_PointerReleased; _calendar.KeyDown -= Calendar_KeyDown; } _calendar = e.NameScope.Find(ElementCalendar); @@ -435,7 +435,7 @@ namespace Avalonia.Controls _calendar.DayButtonMouseUp += Calendar_DayButtonMouseUp; _calendar.DisplayDateChanged += Calendar_DisplayDateChanged; _calendar.SelectedDatesChanged += Calendar_SelectedDatesChanged; - _calendar.PointerPressed += Calendar_PointerPressed; + _calendar.PointerReleased += Calendar_PointerReleased; _calendar.KeyDown += Calendar_KeyDown; //_calendar.SizeChanged += new SizeChangedEventHandler(Calendar_SizeChanged); //_calendar.IsTabStop = true; @@ -831,9 +831,10 @@ namespace Avalonia.Controls } } } - private void Calendar_PointerPressed(object sender, PointerPressedEventArgs e) + private void Calendar_PointerReleased(object sender, PointerReleasedEventArgs e) { - if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) + + if (e.InitialPressMouseButton == MouseButton.Left) { e.Handled = true; } diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs index 27313b0b4c..02a9daee75 100644 --- a/src/Avalonia.Controls/ComboBox.cs +++ b/src/Avalonia.Controls/ComboBox.cs @@ -257,7 +257,7 @@ namespace Avalonia.Controls } /// - protected override void OnPointerPressed(PointerPressedEventArgs e) + protected override void OnPointerReleased(PointerReleasedEventArgs e) { if (!e.Handled) { @@ -276,7 +276,7 @@ namespace Avalonia.Controls } } - base.OnPointerPressed(e); + base.OnPointerReleased(e); } /// diff --git a/src/Avalonia.Controls/Generators/ItemContainerGenerator`1.cs b/src/Avalonia.Controls/Generators/ItemContainerGenerator`1.cs index 3a098593dc..d1fbb25cb1 100644 --- a/src/Avalonia.Controls/Generators/ItemContainerGenerator`1.cs +++ b/src/Avalonia.Controls/Generators/ItemContainerGenerator`1.cs @@ -47,11 +47,7 @@ namespace Avalonia.Controls.Generators { var container = item as T; - if (item == null) - { - return null; - } - else if (container != null) + if (container != null) { return container; } diff --git a/src/Avalonia.Controls/Presenters/TextPresenter.cs b/src/Avalonia.Controls/Presenters/TextPresenter.cs index f5115a2f7c..6a6d37605d 100644 --- a/src/Avalonia.Controls/Presenters/TextPresenter.cs +++ b/src/Avalonia.Controls/Presenters/TextPresenter.cs @@ -77,7 +77,8 @@ namespace Avalonia.Controls.Presenters static TextPresenter() { - AffectsRender(SelectionBrushProperty); + AffectsRender(SelectionBrushProperty, TextBlock.ForegroundProperty, + SelectionForegroundBrushProperty, CaretBrushProperty); AffectsMeasure(TextProperty, PasswordCharProperty, RevealPasswordProperty, TextAlignmentProperty, TextWrappingProperty, TextBlock.FontSizeProperty, TextBlock.FontStyleProperty, TextBlock.FontWeightProperty, TextBlock.FontFamilyProperty); diff --git a/src/Avalonia.Controls/Primitives/Popup.cs b/src/Avalonia.Controls/Primitives/Popup.cs index a676892384..1e5e80d144 100644 --- a/src/Avalonia.Controls/Primitives/Popup.cs +++ b/src/Avalonia.Controls/Primitives/Popup.cs @@ -128,6 +128,7 @@ namespace Avalonia.Controls.Primitives public static readonly StyledProperty TopmostProperty = AvaloniaProperty.Register(nameof(Topmost)); + private bool _isOpenRequested = false; private bool _isOpen; private bool _ignoreIsOpenChanged; private PopupOpenState? _openState; @@ -361,17 +362,19 @@ namespace Avalonia.Controls.Primitives if (placementTarget == null) { - throw new InvalidOperationException("Popup has no logical parent and PlacementTarget is null"); + _isOpenRequested = true; + return; } var topLevel = placementTarget.VisualRoot as TopLevel; if (topLevel == null) { - throw new InvalidOperationException( - "Attempted to open a popup not attached to a TopLevel"); + _isOpenRequested = true; + return; } + _isOpenRequested = false; var popupHost = OverlayPopupHost.CreatePopupHost(placementTarget, DependencyResolver); var handlerCleanup = new CompositeDisposable(5); @@ -492,6 +495,17 @@ namespace Avalonia.Controls.Primitives return new Size(); } + + /// + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnAttachedToVisualTree(e); + if (_isOpenRequested) + { + Open(); + } + } + /// protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e) { @@ -552,6 +566,7 @@ namespace Avalonia.Controls.Primitives private void CloseCore() { + _isOpenRequested = false; if (_openState is null) { using (BeginIgnoringIsOpen()) diff --git a/src/Avalonia.Themes.Default/ComboBox.xaml b/src/Avalonia.Themes.Default/ComboBox.xaml index cced76e850..67151731a8 100644 --- a/src/Avalonia.Themes.Default/ComboBox.xaml +++ b/src/Avalonia.Themes.Default/ComboBox.xaml @@ -26,6 +26,7 @@ + - + - + #FF0066CC #FFFFFFFF #FF000000 - avares://Avalonia.Themes.Fluent/Assets#Roboto + avares://Avalonia.Themes.Fluent/Assets#Inter 14 diff --git a/src/Avalonia.Themes.Fluent/Assets/Inter-Bold.ttf b/src/Avalonia.Themes.Fluent/Assets/Inter-Bold.ttf new file mode 100644 index 0000000000..847ffd191b Binary files /dev/null and b/src/Avalonia.Themes.Fluent/Assets/Inter-Bold.ttf differ diff --git a/src/Avalonia.Themes.Fluent/Assets/Inter-ExtraLight.ttf b/src/Avalonia.Themes.Fluent/Assets/Inter-ExtraLight.ttf new file mode 100644 index 0000000000..33267cd799 Binary files /dev/null and b/src/Avalonia.Themes.Fluent/Assets/Inter-ExtraLight.ttf differ diff --git a/src/Avalonia.Themes.Fluent/Assets/Inter-Light.ttf b/src/Avalonia.Themes.Fluent/Assets/Inter-Light.ttf new file mode 100644 index 0000000000..c22eafe9fb Binary files /dev/null and b/src/Avalonia.Themes.Fluent/Assets/Inter-Light.ttf differ diff --git a/src/Avalonia.Themes.Fluent/Assets/Inter-Medium.ttf b/src/Avalonia.Themes.Fluent/Assets/Inter-Medium.ttf new file mode 100644 index 0000000000..f782894eea Binary files /dev/null and b/src/Avalonia.Themes.Fluent/Assets/Inter-Medium.ttf differ diff --git a/src/Avalonia.Themes.Fluent/Assets/Inter-Regular.ttf b/src/Avalonia.Themes.Fluent/Assets/Inter-Regular.ttf new file mode 100644 index 0000000000..3b7e686e54 Binary files /dev/null and b/src/Avalonia.Themes.Fluent/Assets/Inter-Regular.ttf differ diff --git a/src/Avalonia.Themes.Fluent/Assets/Inter-SemiBold.ttf b/src/Avalonia.Themes.Fluent/Assets/Inter-SemiBold.ttf new file mode 100644 index 0000000000..556e972f48 Binary files /dev/null and b/src/Avalonia.Themes.Fluent/Assets/Inter-SemiBold.ttf differ diff --git a/src/Avalonia.Themes.Fluent/Assets/Inter-Thin.ttf b/src/Avalonia.Themes.Fluent/Assets/Inter-Thin.ttf new file mode 100644 index 0000000000..e49058e33d Binary files /dev/null and b/src/Avalonia.Themes.Fluent/Assets/Inter-Thin.ttf differ diff --git a/src/Avalonia.Themes.Fluent/Assets/Roboto-Black.ttf b/src/Avalonia.Themes.Fluent/Assets/Roboto-Black.ttf deleted file mode 100644 index 38f809991d..0000000000 Binary files a/src/Avalonia.Themes.Fluent/Assets/Roboto-Black.ttf and /dev/null differ diff --git a/src/Avalonia.Themes.Fluent/Assets/Roboto-Bold.ttf b/src/Avalonia.Themes.Fluent/Assets/Roboto-Bold.ttf deleted file mode 100644 index 5fd9dd9eed..0000000000 Binary files a/src/Avalonia.Themes.Fluent/Assets/Roboto-Bold.ttf and /dev/null differ diff --git a/src/Avalonia.Themes.Fluent/Assets/Roboto-Light.ttf b/src/Avalonia.Themes.Fluent/Assets/Roboto-Light.ttf deleted file mode 100644 index 113d545eea..0000000000 Binary files a/src/Avalonia.Themes.Fluent/Assets/Roboto-Light.ttf and /dev/null differ diff --git a/src/Avalonia.Themes.Fluent/Assets/Roboto-Medium.ttf b/src/Avalonia.Themes.Fluent/Assets/Roboto-Medium.ttf deleted file mode 100644 index 98c4538462..0000000000 Binary files a/src/Avalonia.Themes.Fluent/Assets/Roboto-Medium.ttf and /dev/null differ diff --git a/src/Avalonia.Themes.Fluent/Assets/Roboto-Regular.ttf b/src/Avalonia.Themes.Fluent/Assets/Roboto-Regular.ttf deleted file mode 100644 index c1c3700fe5..0000000000 Binary files a/src/Avalonia.Themes.Fluent/Assets/Roboto-Regular.ttf and /dev/null differ diff --git a/src/Avalonia.Themes.Fluent/Assets/Roboto-Thin.ttf b/src/Avalonia.Themes.Fluent/Assets/Roboto-Thin.ttf deleted file mode 100644 index 04b15402d9..0000000000 Binary files a/src/Avalonia.Themes.Fluent/Assets/Roboto-Thin.ttf and /dev/null differ diff --git a/src/Avalonia.Themes.Fluent/CheckBox.xaml b/src/Avalonia.Themes.Fluent/CheckBox.xaml index 73c44c02ab..678ae5c5a3 100644 --- a/src/Avalonia.Themes.Fluent/CheckBox.xaml +++ b/src/Avalonia.Themes.Fluent/CheckBox.xaml @@ -1,13 +1,10 @@ - + - - @@ -133,11 +132,11 @@ - - @@ -213,11 +212,11 @@ - - diff --git a/src/Avalonia.Themes.Fluent/ComboBox.xaml b/src/Avalonia.Themes.Fluent/ComboBox.xaml index a89b18b272..f77f1b582b 100644 --- a/src/Avalonia.Themes.Fluent/ComboBox.xaml +++ b/src/Avalonia.Themes.Fluent/ComboBox.xaml @@ -133,7 +133,8 @@ Padding="{DynamicResource ComboBoxDropdownBorderPadding}" HorizontalAlignment="Stretch" CornerRadius="{DynamicResource OverlayCornerRadius}"> - + - + + Disabled - Test + + Test + Test @@ -17,11 +21,7 @@ - - - - - - - - + HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" /> - - - - - - - - - - - - - - - - - - - - diff --git a/src/Avalonia.Themes.Fluent/MenuItem.xaml b/src/Avalonia.Themes.Fluent/MenuItem.xaml index 3a03ec1acf..1f1dcf22e2 100644 --- a/src/Avalonia.Themes.Fluent/MenuItem.xaml +++ b/src/Avalonia.Themes.Fluent/MenuItem.xaml @@ -123,7 +123,7 @@ MinHeight="{DynamicResource MenuFlyoutThemeMinHeight}" HorizontalAlignment="Stretch" CornerRadius="{DynamicResource OverlayCornerRadius}"> - + - + + + + + + + + + + + + + + + + + + diff --git a/tests/Avalonia.Base.UnitTests/Data/Core/Plugins/DataAnnotationsValidationPluginTests.cs b/tests/Avalonia.Base.UnitTests/Data/Core/Plugins/DataAnnotationsValidationPluginTests.cs index 5c8a941294..1d9524a191 100644 --- a/tests/Avalonia.Base.UnitTests/Data/Core/Plugins/DataAnnotationsValidationPluginTests.cs +++ b/tests/Avalonia.Base.UnitTests/Data/Core/Plugins/DataAnnotationsValidationPluginTests.cs @@ -59,12 +59,12 @@ namespace Avalonia.Markup.UnitTests.Data.Plugins { new BindingNotification(5), new BindingNotification( - new ValidationException(errmsg), + new DataValidationException(errmsg), BindingErrorType.DataValidationError, 3), new BindingNotification(7), new BindingNotification( - new ValidationException(errmsg), + new DataValidationException(errmsg), BindingErrorType.DataValidationError, 11), }, result); diff --git a/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs b/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs index 3ae91c8bba..783215fb5d 100644 --- a/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs @@ -2,7 +2,6 @@ using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; using Avalonia.Controls.Shapes; using Avalonia.Controls.Templates; -using Avalonia.Input; using Avalonia.LogicalTree; using Avalonia.Media; using Avalonia.UnitTests; @@ -27,6 +26,7 @@ namespace Avalonia.Controls.UnitTests Assert.True(target.IsDropDownOpen); _helper.Down(target); + _helper.Up(target); Assert.False(target.IsDropDownOpen); } diff --git a/tests/Avalonia.Controls.UnitTests/Generators/ItemContainerGeneratorTests.cs b/tests/Avalonia.Controls.UnitTests/Generators/ItemContainerGeneratorTests.cs index ff3ad30a88..c5c7737f0d 100644 --- a/tests/Avalonia.Controls.UnitTests/Generators/ItemContainerGeneratorTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Generators/ItemContainerGeneratorTests.cs @@ -144,6 +144,16 @@ namespace Avalonia.Controls.UnitTests.Generators Assert.Equal("bar", container.Content); } + [Fact] + public void Materialize_Should_Create_Containers_When_Item_Is_Null() + { + var owner = new Decorator(); + var target = new ItemContainerGenerator(owner, ListBoxItem.ContentProperty, null); + var container = (ListBoxItem)target.Materialize(0, null).ContainerControl; + + Assert.True(container != null, "The containers is not materialized."); + } + private IList Materialize( IItemContainerGenerator generator, int index, diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs index 53a8db2176..f032186bcd 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs @@ -21,7 +21,50 @@ namespace Avalonia.Controls.UnitTests.Primitives public class PopupTests { protected bool UsePopupHost; - + + [Fact] + public void Popup_Open_Without_Target_Should_Attach_Itself_Later() + { + using (CreateServices()) + { + int openedEvent = 0; + var target = new Popup(); + target.Opened += (s, a) => openedEvent++; + target.IsOpen = true; + + var window = PreparedWindow(target); + window.Show(); + Assert.Equal(1, openedEvent); + } + } + + [Fact] + public void Popup_Without_TopLevel_Shouldnt_Call_Open() + { + int openedEvent = 0; + var target = new Popup(); + target.Opened += (s, a) => openedEvent++; + target.IsOpen = true; + + Assert.Equal(0, openedEvent); + } + + [Fact] + public void Opening_Popup_Shouldnt_Throw_When_Not_In_Visual_Tree() + { + var target = new Popup(); + target.IsOpen = true; + } + + [Fact] + public void Opening_Popup_Shouldnt_Throw_When_In_Tree_Without_TopLevel() + { + Control c = new Control(); + var target = new Popup(); + ((ISetLogicalParent)target).SetParent(c); + target.IsOpen = true; + } + [Fact] public void Setting_Child_Should_Set_Child_Controls_LogicalParent() {