Browse Source

Merge branch 'master' into fix/attached-property-name-generation

pull/12294/head
Mrxx99 3 years ago
committed by GitHub
parent
commit
d090787791
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 31
      samples/ControlCatalog/Models/GDPdLengthConverter.cs
  2. 21
      samples/ControlCatalog/Pages/DataGridPage.xaml
  3. 69
      src/Android/Avalonia.Android/AndroidInputMethod.cs
  4. 108
      src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
  5. 159
      src/Avalonia.Controls.DataGrid/DataGridColumn.cs
  6. 4
      src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs
  7. 17
      src/Avalonia.Controls.DataGrid/DataGridColumns.cs
  8. 1
      src/Avalonia.Controls.DataGrid/DataGridLength.cs

31
samples/ControlCatalog/Models/GDPdLengthConverter.cs

@ -0,0 +1,31 @@
using System;
using System.Globalization;
using Avalonia.Data.Converters;
namespace ControlCatalog.Models;
internal class GDPdLengthConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is double d)
{
return new Avalonia.Controls.DataGridLength(d,Avalonia.Controls.DataGridLengthUnitType.Pixel,d,d);
}
else if (value is decimal d2)
{
var dv =System.Convert.ToDouble(d2);
return new Avalonia.Controls.DataGridLength(dv, Avalonia.Controls.DataGridLengthUnitType.Pixel, dv, dv);
}
return value;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is Avalonia.Controls.DataGridLength width)
{
return System.Convert.ToDecimal(width.DisplayValue);
}
return value;
}
}

21
samples/ControlCatalog/Pages/DataGridPage.xaml

@ -1,11 +1,14 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:local="using:ControlCatalog.Models"
xmlns:lc="using:ControlCatalog.Converter"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:pages="clr-namespace:ControlCatalog.Pages"
x:Class="ControlCatalog.Pages.DataGridPage"
x:DataType="pages:DataGridPage">
<UserControl.Resources>
<local:GDPValueConverter x:Key="GDPConverter" />
<local:GDPdLengthConverter x:Key="GDPWidthConverter"/>
<DataTemplate x:Key="Demo.DataTemplates.CountryHeader" x:DataType="local:Country">
<StackPanel Orientation="Horizontal" Spacing="5">
<PathIcon Height="12" Data="M 255 116 A 1 1 0 0 0 254 117 L 254 130 A 1 1 0 0 0 255 131 A 1 1 0 0 0 256 130 L 256 123.87109 C 256.1125 123.90694 256.2187 123.94195 256.33984 123.97852 C 257.18636 124.23404 258.19155 124.5 259 124.5 C 259.80845 124.5 260.52133 124.2168 261.17773 123.9668 C 261.83414 123.7168 262.43408 123.5 263 123.5 C 263.56592 123.5 264.5612 123.73404 265.37109 123.97852 C 266.18098 124.22299 266.82227 124.4668 266.82227 124.4668 A 0.50005 0.50005 0 0 0 267.5 124 L 267.5 118 A 0.50005 0.50005 0 0 0 267.17773 117.5332 C 267.17773 117.5332 266.50667 117.27701 265.66016 117.02148 C 264.81364 116.76596 263.80845 116.5 263 116.5 C 262.19155 116.5 261.47867 116.7832 260.82227 117.0332 C 260.16586 117.2832 259.56592 117.5 259 117.5 C 258.43408 117.5 257.4388 117.26596 256.62891 117.02148 C 256.39123 116.94974 256.17716 116.87994 255.98047 116.81445 A 1 1 0 0 0 255 116 z M 263 117.5 C 263.56592 117.5 264.5612 117.73404 265.37109 117.97852 C 266.00097 118.16865 266.29646 118.28239 266.5 118.35742 L 266.5 120.29297 C 266.25708 120.21012 265.97978 120.11797 265.66016 120.02148 C 264.81364 119.76596 263.80845 119.5 263 119.5 C 262.19155 119.5 261.47867 119.7832 260.82227 120.0332 C 260.16586 120.2832 259.56592 120.5 259 120.5 C 258.43408 120.5 257.4388 120.26596 256.62891 120.02148 C 256.39971 119.9523 256.19148 119.88388 256 119.82031 L 256 117.87109 C 256.1125 117.90694 256.2187 117.94195 256.33984 117.97852 C 257.18636 118.23404 258.19155 118.5 259 118.5 C 259.80845 118.5 260.52133 118.2168 261.17773 117.9668 C 261.83414 117.7168 262.43408 117.5 263 117.5 z M 263 120.5 C 263.56592 120.5 264.5612 120.73404 265.37109 120.97852 C 265.8714 121.12954 266.2398 121.25641 266.5 121.34961 L 266.5 123.30469 C 266.22286 123.20649 266.12863 123.1629 265.66016 123.02148 C 264.81364 122.76596 263.80845 122.5 263 122.5 C 262.19155 122.5 261.47867 122.7832 260.82227 123.0332 C 260.16586 123.2832 259.56592 123.5 259 123.5 C 258.43408 123.5 257.4388 123.26596 256.62891 123.02148 C 256.39971 122.9523 256.19148 122.88388 256 122.82031 L 256 120.87109 C 256.1125 120.90694 256.2187 120.94195 256.33984 120.97852 C 257.18636 121.23404 258.19155 121.5 259 121.5 C 259.80845 121.5 260.52133 121.2168 261.17773 120.9668 C 261.83414 120.7168 262.43408 120.5 263 120.5 z" />
@ -28,8 +31,18 @@
<TabControl Grid.Row="2">
<TabItem Header="DataGrid">
<DockPanel>
<CheckBox x:Name="ShowGDP" IsChecked="True" Content="Toggle GDP Column Visibility"
DockPanel.Dock="Top"/>
<StackPanel Orientation="Horizontal"
DockPanel.Dock="Top"
Spacing="5">
<CheckBox x:Name="ShowGDP" IsChecked="True" Content="Toggle GDP Column Visibility"/>
<TextBlock Text="GDP Width:" VerticalAlignment="Center"/>
<NumericUpDown x:Name="GDPWidth"
Minimum="200"
Maximum="350"
Width="200"
Increment="10"
Value="200"/>
</StackPanel>
<DataGrid Name="dataGrid1" Margin="12" CanUserResizeColumns="True" CanUserReorderColumns="True" CanUserSortColumns="True" HeadersVisibility="All"
RowBackground="#1000">
<DataGrid.Columns>
@ -38,9 +51,11 @@
<DataGridTextColumn Header="Region" Binding="{Binding Region}" Width="4*" x:DataType="local:Country" />
<DataGridTextColumn Header="Population" Binding="{Binding Population}" Width="3*" x:DataType="local:Country" />
<DataGridTextColumn Header="Area" Binding="{Binding Area}" Width="3*" x:DataType="local:Country" />
<DataGridTextColumn Header="GDP" Binding="{Binding GDP}" Width="3*"
<DataGridTextColumn Header="GDP" Binding="{Binding GDP}"
Width="{Binding #GDPWidth.Value, Mode=TwoWay, Converter={StaticResource GDPWidthConverter}}"
CellTheme="{StaticResource GdpCell}"
MinWidth="200"
MaxWidth="350"
IsVisible="{Binding #ShowGDP.IsChecked}"
x:DataType="local:Country" />
</DataGrid.Columns>

69
src/Android/Avalonia.Android/AndroidInputMethod.cs

@ -18,6 +18,8 @@ namespace Avalonia.Android
public bool IsActive { get; }
public InputMethodManager IMM { get; }
void OnBatchEditedEnded();
}
enum CustomImeFlags
@ -103,6 +105,13 @@ namespace Avalonia.Android
}
private void _client_SelectionChanged(object sender, EventArgs e)
{
if (_inputConnection.IsInBatchEdit)
return;
OnSelectionChanged();
}
private void OnSelectionChanged()
{
var selection = Client.Selection;
@ -113,17 +122,67 @@ namespace Avalonia.Android
private void _client_SurroundingTextChanged(object sender, EventArgs e)
{
if (_inputConnection.IsInBatchEdit)
return;
OnSurroundingTextChanged();
}
public void OnBatchEditedEnded()
{
if (_inputConnection.IsInBatchEdit)
return;
OnSurroundingTextChanged();
OnSelectionChanged();
}
private void OnSurroundingTextChanged()
{
if(_client is null)
{
return;
}
var surroundingText = _client.SurroundingText ?? "";
var editableText = _inputConnection.EditableWrapper.ToString();
_inputConnection.EditableWrapper.IgnoreChange = true;
if (editableText != surroundingText)
{
_inputConnection.EditableWrapper.IgnoreChange = true;
_inputConnection.Editable.Replace(0, _inputConnection.Editable.Length(), surroundingText);
var diff = GetDiff();
_inputConnection.EditableWrapper.IgnoreChange = false;
_inputConnection.Editable.Replace(diff.index, editableText.Length, diff.diff);
var selection = Client.Selection;
_inputConnection.EditableWrapper.IgnoreChange = false;
_imm.UpdateSelection(_host, selection.Start, selection.End, selection.Start, selection.End);
if(diff.index == 0)
{
var selection = _client.Selection;
_client.Selection = new TextSelection(selection.Start, 0);
_client.Selection = selection;
}
}
(int index, string diff) GetDiff()
{
int index = 0;
var longerLength = Math.Max(surroundingText.Length, editableText.Length);
for (int i = 0; i < longerLength; i++)
{
if (surroundingText.Length == i || editableText.Length == i || surroundingText[i] != editableText[i])
{
index = i;
break;
}
}
var diffString = surroundingText.Substring(index, surroundingText.Length - index);
return (index, diffString);
}
}
public void SetCursorRect(Rect rect)

108
src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Runtime.Versioning;
using System.Threading;
using Android.App;
using Android.Content;
using Android.Graphics;
@ -447,19 +448,22 @@ namespace Avalonia.Android.Platform.SkiaPlatform
{
private readonly AvaloniaInputConnection _inputConnection;
public event EventHandler<int> SelectionChanged;
public EditableWrapper(AvaloniaInputConnection inputConnection)
{
_inputConnection = inputConnection;
}
public TextSelection CurrentSelection => new TextSelection(Selection.GetSelectionStart(this), Selection.GetSelectionEnd(this));
public TextSelection CurrentComposition => new TextSelection(BaseInputConnection.GetComposingSpanStart(this), BaseInputConnection.GetComposingSpanEnd(this));
public bool IgnoreChange { get; set; }
public override IEditable Replace(int start, int end, ICharSequence tb)
{
if (!IgnoreChange && start != end)
{
var text = tb.SubSequence(0, tb.Length());
SelectSurroundingTextForDeletion(start, end);
}
@ -470,8 +474,6 @@ namespace Avalonia.Android.Platform.SkiaPlatform
{
if (!IgnoreChange && start != end)
{
var text = tb.SubSequence(tbstart, tbend);
SelectSurroundingTextForDeletion(start, end);
}
@ -490,8 +492,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
private readonly IAndroidInputMethod _inputMethod;
private readonly EditableWrapper _editable;
private bool _commitInProgress;
private (int Start, int End)? _composingRegion;
private TextSelection _selection;
private int _batchLevel = 0;
public AvaloniaInputConnection(TopLevelImpl toplevel, IAndroidInputMethod inputMethod) : base(inputMethod.View, true)
{
@ -510,63 +511,87 @@ namespace Avalonia.Android.Platform.SkiaPlatform
public TopLevelImpl Toplevel => _toplevel;
public bool IsInBatchEdit => _batchLevel > 0;
public override bool SetComposingRegion(int start, int end)
{
_composingRegion = new(start, end);
return base.SetComposingRegion(start, end);
}
public override bool SetComposingText(ICharSequence text, int newCursorPosition)
{
if(_composingRegion != null)
BeginBatchEdit();
_editable.IgnoreChange = true;
try
{
// Select the composing region.
InputMethod.Client.Selection = new TextSelection(_composingRegion.Value.Start, _composingRegion.Value.End);
}
var compositionText = text.SubSequence(0, text.Length());
if (_editable.CurrentComposition.Start > -1)
{
// Select the composing region.
InputMethod.Client.Selection = new TextSelection(_editable.CurrentComposition.Start, _editable.CurrentComposition.End);
}
var compositionText = text.SubSequence(0, text.Length());
if (_inputMethod.IsActive && !_commitInProgress)
if (_inputMethod.IsActive && !_commitInProgress)
{
if (string.IsNullOrEmpty(compositionText))
_inputMethod.View.DispatchKeyEvent(new KeyEvent(KeyEventActions.Down, Keycode.ForwardDel));
else
_toplevel.TextInput(compositionText);
}
base.SetComposingText(text, newCursorPosition);
}
finally
{
if (string.IsNullOrEmpty(compositionText))
_inputMethod.View.DispatchKeyEvent(new KeyEvent(KeyEventActions.Down, Keycode.ForwardDel));
_editable.IgnoreChange = false;
else
_toplevel.TextInput(compositionText);
EndBatchEdit();
}
return true;
}
public override bool BeginBatchEdit()
{
_batchLevel = Interlocked.Increment(ref _batchLevel);
return base.BeginBatchEdit();
}
public override bool EndBatchEdit()
{
_batchLevel = Interlocked.Decrement(ref _batchLevel);
_inputMethod.OnBatchEditedEnded();
return base.EndBatchEdit();
}
public override bool CommitText(ICharSequence text, int newCursorPosition)
{
BeginBatchEdit();
_commitInProgress = true;
var ret = base.CommitText(text, newCursorPosition);
var composingRegion = _editable.CurrentComposition;
var committedText = text.SubSequence(0, text.Length());
var ret = base.CommitText(text, newCursorPosition);
if (_inputMethod.IsActive && !string.IsNullOrEmpty(committedText))
if(composingRegion.Start != -1)
{
if(_composingRegion != null)
{
_inputMethod.Client.Selection = new TextSelection(_composingRegion.Value.Start, _composingRegion.Value.End);
}
InputMethod.Client.Selection = composingRegion;
}
_toplevel.TextInput(committedText);
var committedText = text.SubSequence(0, text.Length());
_composingRegion = null;
}
if (_inputMethod.IsActive)
if (string.IsNullOrEmpty(committedText))
_inputMethod.View.DispatchKeyEvent(new KeyEvent(KeyEventActions.Down, Keycode.ForwardDel));
else
_toplevel.TextInput(committedText);
_commitInProgress = false;
EndBatchEdit();
return ret;
}
public override bool FinishComposingText()
{
_composingRegion = null;
return base.FinishComposingText();
return true;
}
public override bool DeleteSurroundingText(int beforeLength, int afterLength)
@ -575,11 +600,10 @@ namespace Avalonia.Android.Platform.SkiaPlatform
{
EditableWrapper.IgnoreChange = true;
}
var result = base.DeleteSurroundingText(beforeLength, afterLength);
if (InputMethod.IsActive)
{
var selection = _selection;
var selection = _editable.CurrentSelection;
InputMethod.Client.Selection = new TextSelection(selection.Start - beforeLength, selection.End + afterLength);
@ -588,13 +612,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
EditableWrapper.IgnoreChange = true;
}
return result;
}
public override bool SetSelection(int start, int end)
{
_selection = new TextSelection(start, end);
return base.SetSelection(start, end);
return true;
}
public override bool PerformEditorAction([GeneratedEnum] ImeAction actionCode)
@ -630,7 +648,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
return null;
}
var selection = _selection;
var selection = _editable.CurrentSelection;
ExtractedText extract = new ExtractedText
{

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

@ -7,7 +7,6 @@ using Avalonia.Data;
using Avalonia.Interactivity;
using Avalonia.VisualTree;
using Avalonia.Collections;
using Avalonia.Utilities;
using System;
using System.ComponentModel;
using System.Linq;
@ -24,8 +23,6 @@ namespace Avalonia.Controls
{
internal const int DATAGRIDCOLUMN_maximumWidth = 65536;
private const bool DATAGRIDCOLUMN_defaultIsReadOnly = false;
private DataGridLength? _width; // Null by default, null means inherit the Width from the DataGrid
private bool? _isReadOnly;
private double? _maxWidth;
private double? _minWidth;
@ -39,6 +36,7 @@ namespace Avalonia.Controls
private IBinding _clipboardContentBinding;
private ControlTheme _cellTheme;
private Classes _cellStyleClasses;
private bool _setWidthInternalNoCallback;
/// <summary>
/// Initializes a new instance of the <see cref="T:Avalonia.Controls.DataGridColumn" /> class.
@ -214,6 +212,36 @@ namespace Avalonia.Controls
OwningGrid?.OnColumnVisibleStateChanged(this);
NotifyPropertyChanged(change.Property.Name);
}
else if (change.Property == WidthProperty)
{
if (!_settingWidthInternally)
{
InheritsWidth = false;
}
if (_setWidthInternalNoCallback == false)
{
var grid = OwningGrid;
var width = (change as AvaloniaPropertyChangedEventArgs<DataGridLength>).NewValue.Value;
if (grid != null)
{
var oldWidth = (change as AvaloniaPropertyChangedEventArgs<DataGridLength>).OldValue.Value;
if (width.IsStar != oldWidth.IsStar)
{
SetWidthInternalNoCallback(width);
IsInitialDesiredWidthDetermined = false;
grid.OnColumnWidthChanged(this);
}
else
{
Resize(oldWidth, width, false);
}
}
else
{
SetWidthInternalNoCallback(width);
}
}
}
}
@ -549,48 +577,15 @@ namespace Avalonia.Controls
}
}
public static readonly StyledProperty<DataGridLength> WidthProperty = AvaloniaProperty
.Register<DataGridColumn, DataGridLength>(nameof(Width)
, coerce: CoerceWidth
);
public DataGridLength Width
{
get
{
return
_width ??
OwningGrid?.ColumnWidth ??
// We don't have a good choice here because we don't want to make this property nullable, see DevDiv Bugs 196581
DataGridLength.Auto;
}
set
{
if (!_width.HasValue || _width.Value != value)
{
if (!_settingWidthInternally)
{
InheritsWidth = false;
}
if (OwningGrid != null)
{
DataGridLength width = CoerceWidth(value);
if (width.IsStar != Width.IsStar)
{
// If a column has changed either from or to a star value, we want to recalculate all
// star column widths. They are recalculated during Measure based off what the value we set here.
SetWidthInternalNoCallback(width);
IsInitialDesiredWidthDetermined = false;
OwningGrid.OnColumnWidthChanged(this);
}
else
{
// If a column width's value is simply changing, we resize it (to the right only).
Resize(width.Value, width.UnitType, width.DesiredValue, width.DisplayValue, false);
}
}
else
{
SetWidthInternalNoCallback(value);
}
}
}
get => this.GetValue(WidthProperty);
set => SetValue(WidthProperty, value);
}
/// <summary>
@ -812,19 +807,34 @@ namespace Avalonia.Controls
/// on the rest of the star columns. For pixel widths, the desired value is based on the pixel value.
/// For auto widths, the desired value is initialized as the column's minimum width.
/// </summary>
/// <param name="source"></param>
/// <param name="width">The DataGridLength to coerce.</param>
/// <returns>The resultant (coerced) DataGridLength.</returns>
internal DataGridLength CoerceWidth(DataGridLength width)
static DataGridLength CoerceWidth(AvaloniaObject source, DataGridLength width)
{
var target = (DataGridColumn)source;
if (target._setWidthInternalNoCallback)
{
return width;
}
if (!target.IsSet(WidthProperty))
{
return target.OwningGrid?.ColumnWidth ??
DataGridLength.Auto;
}
double desiredValue = width.DesiredValue;
if (double.IsNaN(desiredValue))
{
if (width.IsStar && OwningGrid != null && OwningGrid.ColumnsInternal != null)
if (width.IsStar && target.OwningGrid != null && target.OwningGrid.ColumnsInternal != null)
{
double totalStarValues = 0;
double totalStarDesiredValues = 0;
double totalNonStarDisplayWidths = 0;
foreach (DataGridColumn column in OwningGrid.ColumnsInternal.GetDisplayedColumns(c => c.IsVisible && c != this && !double.IsNaN(c.Width.DesiredValue)))
foreach (DataGridColumn column in target.OwningGrid.ColumnsInternal.GetDisplayedColumns(c => c.IsVisible && c != target && !double.IsNaN(c.Width.DesiredValue)))
{
if (column.Width.IsStar)
{
@ -839,7 +849,7 @@ namespace Avalonia.Controls
if (totalStarValues == 0)
{
// Compute the new star column's desired value based on the available space if there are no other visible star columns
desiredValue = Math.Max(ActualMinWidth, OwningGrid.CellsWidth - totalNonStarDisplayWidths);
desiredValue = Math.Max(target.ActualMinWidth, target.OwningGrid.CellsWidth - totalNonStarDisplayWidths);
}
else
{
@ -853,7 +863,7 @@ namespace Avalonia.Controls
}
else
{
desiredValue = ActualMinWidth;
desiredValue = target.ActualMinWidth;
}
}
@ -862,7 +872,7 @@ namespace Avalonia.Controls
{
displayValue = desiredValue;
}
displayValue = Math.Max(ActualMinWidth, Math.Min(ActualMaxWidth, displayValue));
displayValue = Math.Max(target.ActualMinWidth, Math.Min(target.ActualMaxWidth, displayValue));
return new DataGridLength(width.Value, width.UnitType, desiredValue, displayValue);
}
@ -896,7 +906,7 @@ namespace Avalonia.Controls
};
result[!ContentControl.ContentProperty] = this[!HeaderProperty];
result[!ContentControl.ContentTemplateProperty] = this[!HeaderTemplateProperty];
if (OwningGrid.ColumnHeaderTheme is {} columnTheme)
if (OwningGrid.ColumnHeaderTheme is { } columnTheme)
{
result.SetValue(StyledElement.ThemeProperty, columnTheme, BindingPriority.Template);
}
@ -909,7 +919,7 @@ namespace Avalonia.Controls
/// </summary>
internal void EnsureWidth()
{
SetWidthInternalNoCallback(CoerceWidth(Width));
SetWidthInternalNoCallback(CoerceWidth(this, Width));
}
internal Control GenerateElementInternal(DataGridCell cell, object dataItem)
@ -931,17 +941,17 @@ namespace Avalonia.Controls
/// can only decrease in size by the amount that the columns after it can increase in size.
/// Likewise, the column can only increase in size if other columns can spare the width.
/// </summary>
/// <param name="value">The new Value.</param>
/// <param name="unitType">The new UnitType.</param>
/// <param name="desiredValue">The new DesiredValue.</param>
/// <param name="displayValue">The new DisplayValue.</param>
/// <param name="oldWidth">with before resize.</param>
/// <param name="newWidth">with after resize.</param>
/// <param name="userInitiated">Whether or not this resize was initiated by a user action.</param>
internal void Resize(double value, DataGridLengthUnitType unitType, double desiredValue, double displayValue, bool userInitiated)
// double value, DataGridLengthUnitType unitType, double desiredValue, double displayValue
internal void Resize(DataGridLength oldWidth, DataGridLength newWidth, bool userInitiated)
{
double newValue = value;
double newDesiredValue = desiredValue;
double newDisplayValue = Math.Max(ActualMinWidth, Math.Min(ActualMaxWidth, displayValue));
DataGridLengthUnitType newUnitType = unitType;
double newValue = newWidth.Value;
double newDesiredValue = newWidth.DesiredValue;
double newDisplayValue = Math.Max(ActualMinWidth, Math.Min(ActualMaxWidth, newWidth.DisplayValue));
DataGridLengthUnitType newUnitType = newWidth.UnitType;
int starColumnsCount = 0;
double totalDisplayWidth = 0;
@ -955,11 +965,11 @@ namespace Avalonia.Controls
// If we're using star sizing, we can only resize the column as much as the columns to the
// right will allow (i.e. until they hit their max or min widths).
if (!hasInfiniteAvailableWidth && (starColumnsCount > 0 || (unitType == DataGridLengthUnitType.Star && Width.IsStar && userInitiated)))
if (!hasInfiniteAvailableWidth && (starColumnsCount > 0 || (newUnitType == DataGridLengthUnitType.Star && newWidth.IsStar && userInitiated)))
{
double limitedDisplayValue = Width.DisplayValue;
double limitedDisplayValue = oldWidth.DisplayValue;
double availableIncrease = Math.Max(0, OwningGrid.CellsWidth - totalDisplayWidth);
double desiredChange = newDisplayValue - Width.DisplayValue;
double desiredChange = newDisplayValue - oldWidth.DisplayValue;
if (desiredChange > availableIncrease)
{
// The desired change is greater than the amount of available space,
@ -979,7 +989,7 @@ namespace Avalonia.Controls
// The desired change is negative, so we need to increase the widths of columns to the right.
limitedDisplayValue += desiredChange + OwningGrid.IncreaseColumnWidths(DisplayIndex + 1, -desiredChange, userInitiated);
}
if (ActualCanUserResize || (Width.IsStar && !userInitiated))
if (ActualCanUserResize || (oldWidth.IsStar && !userInitiated))
{
newDisplayValue = limitedDisplayValue;
}
@ -1002,9 +1012,10 @@ namespace Avalonia.Controls
}
}
DataGridLength oldWidth = Width;
SetWidthInternalNoCallback(new DataGridLength(Math.Min(double.MaxValue, newValue), newUnitType, newDesiredValue, newDisplayValue));
if (Width != oldWidth)
newDisplayValue = Math.Min(double.MaxValue, newValue);
newWidth = new DataGridLength(newDisplayValue, newUnitType, newDesiredValue, newDisplayValue);
SetWidthInternalNoCallback(newWidth);
if (newWidth != oldWidth)
{
OwningGrid.OnColumnWidthChanged(this);
}
@ -1052,7 +1063,17 @@ namespace Avalonia.Controls
/// <param name="width">The new Width.</param>
internal void SetWidthInternalNoCallback(DataGridLength width)
{
_width = width;
var originalValue = _setWidthInternalNoCallback;
_setWidthInternalNoCallback = true;
try
{
Width = width;
}
finally
{
_setWidthInternalNoCallback = originalValue;
}
}
/// <summary>
@ -1122,7 +1143,7 @@ namespace Avalonia.Controls
&& OwningGrid.DataConnection != null
&& OwningGrid.DataConnection.SortDescriptions != null)
{
if(CustomSortComparer != null)
if (CustomSortComparer != null)
{
return
OwningGrid.DataConnection.SortDescriptions

4
src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs

@ -785,7 +785,9 @@ namespace Avalonia.Controls
double desiredWidth = _originalWidth + mouseDelta;
desiredWidth = Math.Max(_dragColumn.ActualMinWidth, Math.Min(_dragColumn.ActualMaxWidth, desiredWidth));
_dragColumn.Resize(_dragColumn.Width.Value, _dragColumn.Width.UnitType, _dragColumn.Width.DesiredValue, desiredWidth, true);
_dragColumn.Resize(_dragColumn.Width,
new(_dragColumn.Width.Value, _dragColumn.Width.UnitType, _dragColumn.Width.DesiredValue, desiredWidth),
true);
OwningGrid.UpdateHorizontalOffset(_originalHorizontalOffset);

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

@ -91,7 +91,10 @@ namespace Avalonia.Controls
// this column is newly added, we'll just set its display value directly.
if (UsesStarSizing && column.IsInitialDesiredWidthDetermined)
{
column.Resize(column.Width.Value, column.Width.UnitType, desiredWidth, desiredWidth, false);
var oldWidth = column.Width;
column.Resize(oldWidth,
new(column.Width.Value, column.Width.UnitType, desiredWidth, desiredWidth),
false);
}
else
{
@ -142,7 +145,7 @@ namespace Avalonia.Controls
{
Debug.Assert(dataGridColumn != null);
if (dataGridColumn is DataGridBoundColumn dataGridBoundColumn &&
if (dataGridColumn is DataGridBoundColumn dataGridBoundColumn &&
dataGridBoundColumn.Binding is BindingBase binding)
{
var path = (binding as Binding)?.Path ?? (binding as CompiledBindingExtension)?.Path.ToString();
@ -359,6 +362,7 @@ namespace Avalonia.Controls
if (column.IsVisible && oldValue != column.ActualMaxWidth)
{
DataGridLength oldWitdh = new(oldValue, column.Width.UnitType, column.Width.DesiredValue, column.Width.DesiredValue);
if (column.ActualMaxWidth < column.Width.DisplayValue)
{
// If the maximum width has caused the column to decrease in size, try first to resize
@ -371,7 +375,9 @@ namespace Avalonia.Controls
{
// If the column was previously limited by its maximum value but has more room now,
// attempt to resize the column to its desired width.
column.Resize(column.Width.Value, column.Width.UnitType, column.Width.DesiredValue, column.Width.DesiredValue, false);
column.Resize(oldWitdh,
new (column.Width.Value, column.Width.UnitType, column.Width.DesiredValue, column.Width.DesiredValue),
false);
}
OnColumnWidthChanged(column);
}
@ -388,6 +394,7 @@ namespace Avalonia.Controls
if (column.IsVisible && oldValue != column.ActualMinWidth)
{
DataGridLength oldWitdh = new(oldValue, column.Width.UnitType, column.Width.DesiredValue, column.Width.DesiredValue);
if (column.ActualMinWidth > column.Width.DisplayValue)
{
// If the minimum width has caused the column to increase in size, try first to resize
@ -400,7 +407,9 @@ namespace Avalonia.Controls
{
// If the column was previously limited by its minimum value but but can be smaller now,
// attempt to resize the column to its desired width.
column.Resize(column.Width.Value, column.Width.UnitType, column.Width.DesiredValue, column.Width.DesiredValue, false);
column.Resize(oldWitdh,
new(column.Width.Value, column.Width.UnitType, column.Width.DesiredValue, column.Width.DesiredValue),
false);
}
OnColumnWidthChanged(column);
}

1
src/Avalonia.Controls.DataGrid/DataGridLength.cs

@ -7,7 +7,6 @@ using Avalonia.Utilities;
using System;
using System.ComponentModel;
using System.Globalization;
using Avalonia.Controls.Utils;
namespace Avalonia.Controls
{

Loading…
Cancel
Save