Browse Source

Merge branch 'master' into fixes/5101-contextmenu-in-popup

pull/5491/head
Dan Walmsley 5 years ago
committed by GitHub
parent
commit
d43a2b40fa
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      samples/ControlCatalog/Pages/DataGridPage.xaml
  2. 6
      samples/ControlCatalog/Pages/DataGridPage.xaml.cs
  3. 21
      src/Avalonia.Controls.DataGrid/DataGridBoundColumn.cs
  4. 16
      src/Avalonia.Controls.DataGrid/DataGridColumn.cs
  5. 5
      src/Avalonia.Controls.DataGrid/DataGridColumns.cs
  6. 2
      src/Avalonia.ReactiveUI/AutoDataTemplateBindingHook.cs
  7. 2
      src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj
  8. 12
      src/Avalonia.ReactiveUI/ReactiveUserControl.cs
  9. 14
      src/Avalonia.ReactiveUI/ReactiveWindow.cs
  10. 16
      src/Avalonia.ReactiveUI/RoutedViewHost.cs
  11. 16
      src/Avalonia.ReactiveUI/TransitioningContentControl.cs
  12. 12
      src/Avalonia.ReactiveUI/ViewModelViewHost.cs
  13. 11
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CompiledBindingPath.cs
  14. 6
      src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs

5
samples/ControlCatalog/Pages/DataGridPage.xaml

@ -1,5 +1,5 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:local="clr-namespace:ControlCatalog.Models;assembly=ControlCatalog"
xmlns:local="using:ControlCatalog.Models"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.Pages.DataGridPage">
<UserControl.Resources>
@ -26,7 +26,8 @@
<DataGrid Name="dataGrid1" Margin="12" CanUserResizeColumns="True" CanUserReorderColumns="True" CanUserSortColumns="True" HeadersVisibility="All">
<DataGrid.Columns>
<DataGridTextColumn Header="Country" Binding="{Binding Name}" Width="6*" />
<DataGridTextColumn Header="Region" Binding="{Binding Region}" Width="4*" />
<!-- CompiledBinding example of usage. -->
<DataGridTextColumn Header="Region" Binding="{CompiledBinding Region}" Width="4*" x:DataType="local:Country" />
<DataGridTextColumn Header="Population" Binding="{Binding Population}" Width="3*" />
<DataGridTextColumn Header="Area" Binding="{Binding Area}" Width="3*" />
<DataGridTextColumn Header="GDP" Binding="{Binding GDP}" Width="3*" CellStyleClasses="gdp" />

6
samples/ControlCatalog/Pages/DataGridPage.xaml.cs

@ -24,8 +24,10 @@ namespace ControlCatalog.Pages
dg1.LoadingRow += Dg1_LoadingRow;
dg1.Sorting += (s, a) =>
{
var property = ((a.Column as DataGridBoundColumn)?.Binding as Binding).Path;
if (property == dataGridSortDescription.PropertyPath
var binding = (a.Column as DataGridBoundColumn)?.Binding as Binding;
if (binding?.Path is string property
&& property == dataGridSortDescription.PropertyPath
&& !collectionView1.SortDescriptions.Contains(dataGridSortDescription))
{
collectionView1.SortDescriptions.Add(dataGridSortDescription);

21
src/Avalonia.Controls.DataGrid/DataGridBoundColumn.cs

@ -10,7 +10,8 @@ using System.Reactive.Disposables;
using System.Reactive.Subjects;
using Avalonia.Reactive;
using System.Diagnostics;
using Avalonia.Controls.Utils;
using Avalonia.Controls.Utils;
using Avalonia.Markup.Xaml.MarkupExtensions;
namespace Avalonia.Controls
{
@ -47,14 +48,15 @@ namespace Avalonia.Controls
if (_binding != null)
{
if(_binding is Avalonia.Data.Binding binding)
if(_binding is BindingBase binding)
{
if (binding.Mode == BindingMode.OneWayToSource)
{
throw new InvalidOperationException("DataGridColumn doesn't support BindingMode.OneWayToSource. Use BindingMode.TwoWay instead.");
}
if (!String.IsNullOrEmpty(binding.Path) && binding.Mode == BindingMode.Default)
var path = (binding as Binding)?.Path ?? (binding as CompiledBindingExtension)?.Path.ToString();
if (!string.IsNullOrEmpty(path) && binding.Mode == BindingMode.Default)
{
binding.Mode = BindingMode.TwoWay;
}
@ -136,13 +138,16 @@ namespace Avalonia.Controls
internal void SetHeaderFromBinding()
{
if (OwningGrid != null && OwningGrid.DataConnection.DataType != null
&& Header == null && Binding != null && Binding is Binding binding
&& !String.IsNullOrWhiteSpace(binding.Path))
&& Header == null && Binding != null && Binding is BindingBase binding)
{
string header = OwningGrid.DataConnection.DataType.GetDisplayName(binding.Path);
if (header != null)
var path = (binding as Binding)?.Path ?? (binding as CompiledBindingExtension)?.Path.ToString();
if (!string.IsNullOrWhiteSpace(path))
{
Header = header;
var header = OwningGrid.DataConnection.DataType.GetDisplayName(path);
if (header != null)
{
Header = header;
}
}
}
}

16
src/Avalonia.Controls.DataGrid/DataGridColumn.cs

@ -12,6 +12,7 @@ using System;
using System.Linq;
using System.Diagnostics;
using Avalonia.Controls.Utils;
using Avalonia.Markup.Xaml.MarkupExtensions;
namespace Avalonia.Controls
{
@ -1033,13 +1034,16 @@ namespace Avalonia.Controls
if (String.IsNullOrEmpty(result))
{
if(this is DataGridBoundColumn boundColumn &&
boundColumn.Binding != null &&
boundColumn.Binding is Binding binding &&
binding.Path != null)
if (this is DataGridBoundColumn boundColumn)
{
result = binding.Path;
if (boundColumn.Binding is Binding binding)
{
result = binding.Path;
}
else if (boundColumn.Binding is CompiledBindingExtension compiledBinding)
{
result = compiledBinding.Path.ToString();
}
}
}

5
src/Avalonia.Controls.DataGrid/DataGridColumns.cs

@ -5,6 +5,7 @@
using Avalonia.Controls.Utils;
using Avalonia.Data;
using Avalonia.Markup.Xaml.MarkupExtensions;
using Avalonia.Utilities;
using System;
using System.Collections.Generic;
@ -141,9 +142,9 @@ namespace Avalonia.Controls
Debug.Assert(dataGridColumn != null);
if (dataGridColumn is DataGridBoundColumn dataGridBoundColumn &&
dataGridBoundColumn.Binding is Binding binding)
dataGridBoundColumn.Binding is BindingBase binding)
{
string path = binding.Path;
var path = (binding as Binding)?.Path ?? (binding as CompiledBindingExtension)?.Path.ToString();
if (string.IsNullOrWhiteSpace(path))
{

2
src/Avalonia.ReactiveUI/AutoDataTemplateBindingHook.cs

@ -29,7 +29,7 @@ namespace Avalonia.ReactiveUI
/// <inheritdoc/>
public bool ExecuteHook(
object source, object target,
object? source, object target,
Func<IObservedChange<object, object>[]> getCurrentViewModelProperties,
Func<IObservedChange<object, object>[]> getCurrentViewProperties,
BindingDirection direction)

2
src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj

@ -3,6 +3,8 @@
<TargetFramework>netstandard2.0</TargetFramework>
<PackageId>Avalonia.ReactiveUI</PackageId>
<SignAssembly>false</SignAssembly>
<Nullable>enable</Nullable>
<WarningsAsErrors>nullable</WarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\packages\Avalonia\Avalonia.csproj" />

12
src/Avalonia.ReactiveUI/ReactiveUserControl.cs

@ -17,8 +17,8 @@ namespace Avalonia.ReactiveUI
/// <typeparam name="TViewModel">ViewModel type.</typeparam>
public class ReactiveUserControl<TViewModel> : UserControl, IViewFor<TViewModel> where TViewModel : class
{
public static readonly StyledProperty<TViewModel> ViewModelProperty = AvaloniaProperty
.Register<ReactiveUserControl<TViewModel>, TViewModel>(nameof(ViewModel));
public static readonly StyledProperty<TViewModel?> ViewModelProperty = AvaloniaProperty
.Register<ReactiveUserControl<TViewModel>, TViewModel?>(nameof(ViewModel));
/// <summary>
/// Initializes a new instance of the <see cref="ReactiveUserControl{TViewModel}"/> class.
@ -34,16 +34,16 @@ namespace Avalonia.ReactiveUI
/// <summary>
/// The ViewModel.
/// </summary>
public TViewModel ViewModel
public TViewModel? ViewModel
{
get => GetValue(ViewModelProperty);
set => SetValue(ViewModelProperty, value);
}
object IViewFor.ViewModel
object? IViewFor.ViewModel
{
get => ViewModel;
set => ViewModel = (TViewModel)value;
set => ViewModel = (TViewModel?)value;
}
protected override void OnDataContextChanged(EventArgs e)
@ -51,7 +51,7 @@ namespace Avalonia.ReactiveUI
ViewModel = DataContext as TViewModel;
}
private void OnViewModelChanged(object value)
private void OnViewModelChanged(object? value)
{
if (value == null)
{

14
src/Avalonia.ReactiveUI/ReactiveWindow.cs

@ -17,8 +17,8 @@ namespace Avalonia.ReactiveUI
/// <typeparam name="TViewModel">ViewModel type.</typeparam>
public class ReactiveWindow<TViewModel> : Window, IViewFor<TViewModel> where TViewModel : class
{
public static readonly StyledProperty<TViewModel> ViewModelProperty = AvaloniaProperty
.Register<ReactiveWindow<TViewModel>, TViewModel>(nameof(ViewModel));
public static readonly StyledProperty<TViewModel?> ViewModelProperty = AvaloniaProperty
.Register<ReactiveWindow<TViewModel>, TViewModel?>(nameof(ViewModel));
/// <summary>
/// Initializes a new instance of the <see cref="ReactiveWindow{TViewModel}"/> class.
@ -35,19 +35,19 @@ namespace Avalonia.ReactiveUI
/// <summary>
/// The ViewModel.
/// </summary>
public TViewModel ViewModel
public TViewModel? ViewModel
{
get => GetValue(ViewModelProperty);
set => SetValue(ViewModelProperty, value);
}
object IViewFor.ViewModel
object? IViewFor.ViewModel
{
get => ViewModel;
set => ViewModel = (TViewModel)value;
set => ViewModel = (TViewModel?)value;
}
private void OnDataContextChanged(object value)
private void OnDataContextChanged(object? value)
{
if (value is TViewModel viewModel)
{
@ -59,7 +59,7 @@ namespace Avalonia.ReactiveUI
}
}
private void OnViewModelChanged(object value)
private void OnViewModelChanged(object? value)
{
if (value == null)
{

16
src/Avalonia.ReactiveUI/RoutedViewHost.cs

@ -55,8 +55,8 @@ namespace Avalonia.ReactiveUI
/// <summary>
/// <see cref="AvaloniaProperty"/> for the <see cref="Router"/> property.
/// </summary>
public static readonly StyledProperty<RoutingState> RouterProperty =
AvaloniaProperty.Register<RoutedViewHost, RoutingState>(nameof(Router));
public static readonly StyledProperty<RoutingState?> RouterProperty =
AvaloniaProperty.Register<RoutedViewHost, RoutingState?>(nameof(Router));
/// <summary>
/// Initializes a new instance of the <see cref="RoutedViewHost"/> class.
@ -67,12 +67,12 @@ namespace Avalonia.ReactiveUI
{
var routerRemoved = this
.WhenAnyValue(x => x.Router)
.Where(router => router == null)
.Cast<object>();
.Where(router => router == null)!
.Cast<object?>();
this.WhenAnyValue(x => x.Router)
.Where(router => router != null)
.SelectMany(router => router.CurrentViewModel)
.SelectMany(router => router!.CurrentViewModel)
.Merge(routerRemoved)
.Subscribe(NavigateToViewModel)
.DisposeWith(disposables);
@ -82,7 +82,7 @@ namespace Avalonia.ReactiveUI
/// <summary>
/// Gets or sets the <see cref="RoutingState"/> of the view model stack.
/// </summary>
public RoutingState Router
public RoutingState? Router
{
get => GetValue(RouterProperty);
set => SetValue(RouterProperty, value);
@ -91,13 +91,13 @@ namespace Avalonia.ReactiveUI
/// <summary>
/// Gets or sets the ReactiveUI view locator used by this router.
/// </summary>
public IViewLocator ViewLocator { get; set; }
public IViewLocator? ViewLocator { get; set; }
/// <summary>
/// Invoked when ReactiveUI router navigates to a view model.
/// </summary>
/// <param name="viewModel">ViewModel to which the user navigates.</param>
private void NavigateToViewModel(object viewModel)
private void NavigateToViewModel(object? viewModel)
{
if (Router == null)
{

16
src/Avalonia.ReactiveUI/TransitioningContentControl.cs

@ -13,20 +13,20 @@ namespace Avalonia.ReactiveUI
/// <summary>
/// <see cref="AvaloniaProperty"/> for the <see cref="PageTransition"/> property.
/// </summary>
public static readonly StyledProperty<IPageTransition> PageTransitionProperty =
AvaloniaProperty.Register<TransitioningContentControl, IPageTransition>(nameof(PageTransition),
public static readonly StyledProperty<IPageTransition?> PageTransitionProperty =
AvaloniaProperty.Register<TransitioningContentControl, IPageTransition?>(nameof(PageTransition),
new CrossFade(TimeSpan.FromSeconds(0.5)));
/// <summary>
/// <see cref="AvaloniaProperty"/> for the <see cref="DefaultContent"/> property.
/// </summary>
public static readonly StyledProperty<object> DefaultContentProperty =
AvaloniaProperty.Register<TransitioningContentControl, object>(nameof(DefaultContent));
public static readonly StyledProperty<object?> DefaultContentProperty =
AvaloniaProperty.Register<TransitioningContentControl, object?>(nameof(DefaultContent));
/// <summary>
/// Gets or sets the animation played when content appears and disappears.
/// </summary>
public IPageTransition PageTransition
public IPageTransition? PageTransition
{
get => GetValue(PageTransitionProperty);
set => SetValue(PageTransitionProperty, value);
@ -35,7 +35,7 @@ namespace Avalonia.ReactiveUI
/// <summary>
/// Gets or sets the content displayed whenever there is no page currently routed.
/// </summary>
public object DefaultContent
public object? DefaultContent
{
get => GetValue(DefaultContentProperty);
set => SetValue(DefaultContentProperty, value);
@ -44,7 +44,7 @@ namespace Avalonia.ReactiveUI
/// <summary>
/// Gets or sets the content with animation.
/// </summary>
public new object Content
public new object? Content
{
get => base.Content;
set => UpdateContentWithTransition(value);
@ -60,7 +60,7 @@ namespace Avalonia.ReactiveUI
/// Updates the content with transitions.
/// </summary>
/// <param name="content">New content to set.</param>
private async void UpdateContentWithTransition(object content)
private async void UpdateContentWithTransition(object? content)
{
if (PageTransition != null)
await PageTransition.Start(this, null, true);

12
src/Avalonia.ReactiveUI/ViewModelViewHost.cs

@ -15,8 +15,8 @@ namespace Avalonia.ReactiveUI
/// <summary>
/// <see cref="AvaloniaProperty"/> for the <see cref="ViewModel"/> property.
/// </summary>
public static readonly AvaloniaProperty<object> ViewModelProperty =
AvaloniaProperty.Register<ViewModelViewHost, object>(nameof(ViewModel));
public static readonly AvaloniaProperty<object?> ViewModelProperty =
AvaloniaProperty.Register<ViewModelViewHost, object?>(nameof(ViewModel));
/// <summary>
/// Initializes a new instance of the <see cref="ViewModelViewHost"/> class.
@ -34,7 +34,7 @@ namespace Avalonia.ReactiveUI
/// <summary>
/// Gets or sets the ViewModel to display.
/// </summary>
public object ViewModel
public object? ViewModel
{
get => GetValue(ViewModelProperty);
set => SetValue(ViewModelProperty, value);
@ -43,13 +43,13 @@ namespace Avalonia.ReactiveUI
/// <summary>
/// Gets or sets the view locator.
/// </summary>
public IViewLocator ViewLocator { get; set; }
public IViewLocator? ViewLocator { get; set; }
/// <summary>
/// Invoked when ReactiveUI router navigates to a view model.
/// </summary>
/// <param name="viewModel">ViewModel to which the user navigates.</param>
private void NavigateToViewModel(object viewModel)
private void NavigateToViewModel(object? viewModel)
{
if (viewModel == null)
{
@ -74,4 +74,4 @@ namespace Avalonia.ReactiveUI
Content = viewInstance;
}
}
}
}

11
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CompiledBindingPath.cs

@ -72,7 +72,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
internal object RawSource { get; }
public override string ToString()
=> string.Concat(_elements.Select(e => e.ToString()));
=> string.Concat(_elements);
}
public class CompiledBindingPathBuilder
@ -88,7 +88,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
public CompiledBindingPathBuilder Property(IPropertyInfo info, Func<WeakReference<object>, IPropertyInfo, IPropertyAccessor> accessorFactory)
{
_elements.Add(new PropertyElement(info, accessorFactory));
_elements.Add(new PropertyElement(info, accessorFactory, _elements.Count == 0));
return this;
}
@ -161,10 +161,13 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
internal class PropertyElement : ICompiledBindingPathElement
{
public PropertyElement(IPropertyInfo property, Func<WeakReference<object>, IPropertyInfo, IPropertyAccessor> accessorFactory)
private readonly bool _isFirstElement;
public PropertyElement(IPropertyInfo property, Func<WeakReference<object>, IPropertyInfo, IPropertyAccessor> accessorFactory, bool isFirstElement)
{
Property = property;
AccessorFactory = accessorFactory;
_isFirstElement = isFirstElement;
}
public IPropertyInfo Property { get; }
@ -172,7 +175,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
public Func<WeakReference<object>, IPropertyInfo, IPropertyAccessor> AccessorFactory { get; }
public override string ToString()
=> $".{Property.Name}";
=> _isFirstElement ? Property.Name : $".{Property.Name}";
}
internal interface IStronglyTypedStreamElement : ICompiledBindingPathElement

6
src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs

@ -1438,15 +1438,15 @@ namespace Avalonia.Win32.Interop
}
[DllImport("ntdll")]
private static extern int RtlGetVersion(out RTL_OSVERSIONINFOEX lpVersionInformation);
private static extern int RtlGetVersion(ref RTL_OSVERSIONINFOEX lpVersionInformation);
internal static Version RtlGetVersion()
{
RTL_OSVERSIONINFOEX v = new RTL_OSVERSIONINFOEX();
v.dwOSVersionInfoSize = (uint)Marshal.SizeOf(v);
if (RtlGetVersion(out v) == 0)
if (RtlGetVersion(ref v) == 0)
{
return new Version((int)v.dwMajorVersion, (int)v.dwMinorVersion, (int)v.dwBuildNumber, (int)v.dwPlatformId);
return new Version((int)v.dwMajorVersion, (int)v.dwMinorVersion, (int)v.dwBuildNumber);
}
else
{

Loading…
Cancel
Save