diff --git a/src/Microsoft.DotNet.Wpf/ApiCompat/Baselines/PresentationFramework-ref.baseline.txt b/src/Microsoft.DotNet.Wpf/ApiCompat/Baselines/PresentationFramework-ref.baseline.txt index d4b7ffccb6b..41d65269487 100644 --- a/src/Microsoft.DotNet.Wpf/ApiCompat/Baselines/PresentationFramework-ref.baseline.txt +++ b/src/Microsoft.DotNet.Wpf/ApiCompat/Baselines/PresentationFramework-ref.baseline.txt @@ -93,7 +93,9 @@ CannotChangeAttribute : Attribute 'System.Windows.LocalizabilityAttribute' on 'S CannotChangeAttribute : Attribute 'System.Windows.LocalizabilityAttribute' on 'System.Windows.Controls.Expander' changed from '[LocalizabilityAttribute(0, Readability=0)]' in the contract to '[LocalizabilityAttribute(LocalizationCategory.None, Readability=Readability.Unreadable)]' in the implementation. CannotChangeAttribute : Attribute 'System.Windows.LocalizabilityAttribute' on 'System.Windows.Controls.Frame' changed from '[LocalizabilityAttribute(16)]' in the contract to '[LocalizabilityAttribute(LocalizationCategory.Ignore)]' in the implementation. CannotChangeAttribute : Attribute 'System.ComponentModel.DesignerSerializationVisibilityAttribute' on 'System.Windows.Controls.Grid.ColumnDefinitions' changed from '[DesignerSerializationVisibilityAttribute(2)]' in the contract to '[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content)]' in the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Windows.Controls.Grid.ColumnDefinitions' in the contract but not the implementation. CannotChangeAttribute : Attribute 'System.ComponentModel.DesignerSerializationVisibilityAttribute' on 'System.Windows.Controls.Grid.RowDefinitions' changed from '[DesignerSerializationVisibilityAttribute(2)]' in the contract to '[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content)]' in the implementation. +CannotRemoveAttribute : Attribute 'System.ComponentModel.TypeConverterAttribute' exists on 'System.Windows.Controls.Grid.RowDefinitions' in the contract but not the implementation. CannotChangeAttribute : Attribute 'System.ComponentModel.DesignerSerializationVisibilityAttribute' on 'System.Windows.Controls.GridView.ColumnHeaderTemplateSelector' changed from '[DesignerSerializationVisibilityAttribute(0)]' in the contract to '[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]' in the implementation. CannotChangeAttribute : Attribute 'System.ComponentModel.DesignerSerializationVisibilityAttribute' on 'System.Windows.Controls.GridView.Columns' changed from '[DesignerSerializationVisibilityAttribute(2)]' in the contract to '[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content)]' in the implementation. CannotChangeAttribute : Attribute 'System.Windows.LocalizabilityAttribute' on 'System.Windows.Controls.GridViewColumn' changed from '[LocalizabilityAttribute(0, Readability=0)]' in the contract to '[LocalizabilityAttribute(LocalizationCategory.None, Readability=Readability.Unreadable)]' in the implementation. @@ -261,4 +263,4 @@ CannotChangeAttribute : Attribute 'System.ComponentModel.DesignerSerializationVi CannotChangeAttribute : Attribute 'System.Windows.Markup.DesignerSerializationOptionsAttribute' on 'System.Windows.Markup.XmlAttributeProperties.GetXmlSpace(System.Windows.DependencyObject)' changed from '[DesignerSerializationOptionsAttribute(1)]' in the contract to '[DesignerSerializationOptionsAttribute(DesignerSerializationOptions.SerializeAsAttribute)]' in the implementation. CannotChangeAttribute : Attribute 'System.ComponentModel.DesignerSerializationVisibilityAttribute' on 'System.Windows.Media.Animation.Storyboard.GetTarget(System.Windows.DependencyObject)' changed from '[DesignerSerializationVisibilityAttribute(0)]' in the contract to '[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]' in the implementation. CannotChangeAttribute : Attribute 'System.Windows.LocalizabilityAttribute' on 'System.Windows.Shapes.Shape' changed from '[LocalizabilityAttribute(0, Readability=0)]' in the contract to '[LocalizabilityAttribute(LocalizationCategory.None, Readability=Readability.Unreadable)]' in the implementation. -Total Issues: 262 +Total Issues: 264 diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/PresentationFramework.csproj b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/PresentationFramework.csproj index 9572a2184d0..56c15c3ef3a 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/PresentationFramework.csproj +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/PresentationFramework.csproj @@ -548,6 +548,7 @@ + @@ -740,6 +741,7 @@ + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ColumnDefinition.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ColumnDefinition.cs index 6962180fe76..aa2f23f5c48 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ColumnDefinition.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ColumnDefinition.cs @@ -70,6 +70,11 @@ internal ColumnDefinitionCollection(Grid owner) PrivateOnModified(); } + public ColumnDefinitionCollection() + { + PrivateOnModified(); + } + #endregion Constructors //------------------------------------------------------ @@ -393,6 +398,10 @@ bool IList.IsFixedSize { get { + if (_owner == null) + { + return false; + } return ( _owner.MeasureOverrideInProgress || _owner.ArrangeOverrideInProgress ); } @@ -406,6 +415,10 @@ bool IList.IsFixedSize { get { + if (_owner == null) + { + return false; + } return ( _owner.MeasureOverrideInProgress || _owner.ArrangeOverrideInProgress ); } @@ -511,6 +524,46 @@ internal void InternalTrimToSize() #region Internal Properties + /// + /// Owner property. + /// + internal Grid Owner + { + get { return (_owner); } + set + { + if (_owner == value) + { + return; + } + + if (_owner == null) + { + _owner = value; + PrivateOnModified(); + for (int i = 0; i < _size; i++) + { + _owner.AddLogicalChild(_items[i]); + _items[i].OnEnterParentTree(); + } + } + else if (value == null) + { + PrivateOnModified(); + for (int i = 0; i < _size; i++) + { + _items[i].OnExitParentTree(); + _owner.RemoveLogicalChild(_items[i]); + } + _owner = null; + } + else + { + throw new ArgumentException(SR.Format(SR.GridCollection_InOtherCollection, "value", "ColumnDefinitionCollection")); + } + } + } + /// /// Internal version of Count. /// @@ -604,7 +657,7 @@ private void PrivateConnectChild(int index, DefinitionBase value) _items[index] = value; value.Index = index; - _owner.AddLogicalChild(value); + _owner?.AddLogicalChild(value); value.OnEnterParentTree(); } @@ -623,7 +676,7 @@ private void PrivateDisconnectChild(DefinitionBase value) _items[value.Index] = null; value.Index = -1; - _owner.RemoveLogicalChild(value); + _owner?.RemoveLogicalChild(value); } /// @@ -696,8 +749,11 @@ private void PrivateRemove(DefinitionBase value) private void PrivateOnModified() { _version++; - _owner.ColumnDefinitionCollectionDirty = true; - _owner.Invalidate(); + if (_owner != null) + { + _owner.ColumnDefinitionCollectionDirty = true; + _owner.Invalidate(); + } } /// @@ -731,7 +787,7 @@ private void PrivateSetCapacity(int value) //------------------------------------------------------ #region Private Fields - private readonly Grid _owner; // owner of the collection + private Grid _owner; // owner of the collection private DefinitionBase[] _items; // storage of items private int _size; // size of the collection private int _version; // version tracks updates in the collection diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ColumnDefinitionCollectionConverter.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ColumnDefinitionCollectionConverter.cs new file mode 100644 index 00000000000..00211c5b3a8 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ColumnDefinitionCollectionConverter.cs @@ -0,0 +1,75 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.ComponentModel; +using System.Windows.Controls; +using System.Windows.Markup; +using System.Globalization; +using System.Text; +using MS.Internal; + +namespace System.Windows.Controls +{ + internal sealed class ColumnDefinitionCollectionConverter : TypeConverter + { + #region Public Methods + + /// + /// CanConvertFrom - Returns whether or not this class can convert from a given type. + /// + /// + /// bool - True if this converter can convert from the provided type, false if not. + /// + /// The ITypeDescriptorContext for this call. + /// The Type being queried for support. + public override bool CanConvertFrom(ITypeDescriptorContext typeDescriptorContext, Type sourceType) + { + return sourceType == typeof(string); + } + + /// + /// ConvertFrom - Attempt to convert to a ColumnDefinitionCollection from the given object. + /// + /// + /// The object which was constructed. + /// + /// + /// An ArgumentNullException is thrown if the example object is null. + /// + /// The ITypeDescriptorContext for this call. + /// The CultureInfo which is respected when converting. + /// The Thickness to convert. + public override object ConvertFrom(ITypeDescriptorContext typeDescriptorContext, CultureInfo cultureInfo, object value) + { + if (value is string input) + { + ColumnDefinitionCollection collection = new ColumnDefinitionCollection(); + + TokenizerHelper th = new TokenizerHelper(input, cultureInfo); + while (th.NextToken()) + { + collection.Add(new ColumnDefinition { Width = GridLengthConverter.FromString(th.GetCurrentToken(), cultureInfo) }); + } + + return collection; + } + throw GetConvertFromException(value); + } + + /// + /// CanConvertTo - Returns whether or not this class can convert to a given type. + /// + /// + /// bool - True if this converter can convert to the provided type, false if not. + /// + /// The ITypeDescriptorContext for this call. + /// The Type being queried for support. + public override bool CanConvertTo(ITypeDescriptorContext typeDescriptorContext, Type destinationType) + { + return false; + } + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Grid.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Grid.cs index 7e7a8040c82..a0f15c5ade7 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Grid.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Grid.cs @@ -272,6 +272,7 @@ public bool ShowGridLines /// /// Returns a ColumnDefinitionCollection of column definitions. /// + [TypeConverter(typeof(ColumnDefinitionCollectionConverter))] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public ColumnDefinitionCollection ColumnDefinitions { @@ -282,11 +283,40 @@ public ColumnDefinitionCollection ColumnDefinitions return (_data.ColumnDefinitions); } + set + { + if (value?.Owner == this) + { + return; + } + + if (value?.Owner is not null) + { + throw new ArgumentException(SR.Format(SR.GridCollection_InOtherCollection, "value", "ColumnDefinitionCollection")); + } + + _data ??= new ExtendedData(); + if (_data?.ColumnDefinitions is { } cd) + { + cd.Owner = null; + } + + if (value is null) + { + _data.ColumnDefinitions = new ColumnDefinitionCollection(this); + } + else + { + value.Owner = this; + _data.ColumnDefinitions = value; + } + } } /// /// Returns a RowDefinitionCollection of row definitions. /// + [TypeConverter(typeof(RowDefinitionCollectionConverter))] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public RowDefinitionCollection RowDefinitions { @@ -297,6 +327,34 @@ public RowDefinitionCollection RowDefinitions return (_data.RowDefinitions); } + set + { + if (value?.Owner == this) + { + return; + } + + if (value?.Owner is not null) + { + throw new ArgumentException(SR.Format(SR.GridCollection_InOtherCollection, "value", "RowDefinitionCollection")); + } + + _data ??= new ExtendedData(); + if (_data?.RowDefinitions is { } rd) + { + rd.Owner = null; + } + + if (value is null) + { + _data.RowDefinitions = new RowDefinitionCollection(this); + } + else + { + value.Owner = this; + _data.RowDefinitions = value; + } + } } #endregion Public Properties diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/RowDefinition.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/RowDefinition.cs index b50920ea489..dac99b63996 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/RowDefinition.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/RowDefinition.cs @@ -70,6 +70,11 @@ internal RowDefinitionCollection(Grid owner) PrivateOnModified(); } + public RowDefinitionCollection() + { + PrivateOnModified(); + } + #endregion Constructors //------------------------------------------------------ @@ -393,6 +398,10 @@ bool IList.IsFixedSize { get { + if (_owner == null) + { + return false; + } return ( _owner.MeasureOverrideInProgress || _owner.ArrangeOverrideInProgress ); } @@ -406,6 +415,10 @@ bool IList.IsFixedSize { get { + if (_owner == null) + { + return false; + } return ( _owner.MeasureOverrideInProgress || _owner.ArrangeOverrideInProgress ); } @@ -511,6 +524,46 @@ internal void InternalTrimToSize() #region Internal Properties + /// + /// Owner property. + /// + internal Grid Owner + { + get { return (_owner); } + set + { + if (_owner == value) + { + return; + } + + if (_owner == null) + { + _owner = value; + PrivateOnModified(); + for (int i = 0; i < _size; i++) + { + _owner.AddLogicalChild(_items[i]); + _items[i].OnEnterParentTree(); + } + } + else if (value == null) + { + PrivateOnModified(); + for (int i = 0; i < _size; i++) + { + _items[i].OnExitParentTree(); + _owner.RemoveLogicalChild(_items[i]); + } + _owner = null; + } + else + { + throw new ArgumentException(SR.Format(SR.GridCollection_InOtherCollection, "value", "RowDefinitionCollection")); + } + } + } + /// /// Internal version of Count. /// @@ -604,7 +657,7 @@ private void PrivateConnectChild(int index, DefinitionBase value) _items[index] = value; value.Index = index; - _owner.AddLogicalChild(value); + _owner?.AddLogicalChild(value); value.OnEnterParentTree(); } @@ -623,7 +676,7 @@ private void PrivateDisconnectChild(DefinitionBase value) _items[value.Index] = null; value.Index = -1; - _owner.RemoveLogicalChild(value); + _owner?.RemoveLogicalChild(value); } /// @@ -696,8 +749,11 @@ private void PrivateRemove(DefinitionBase value) private void PrivateOnModified() { _version++; - _owner.RowDefinitionCollectionDirty = true; - _owner.Invalidate(); + if (_owner != null) + { + _owner.RowDefinitionCollectionDirty = true; + _owner.Invalidate(); + } } /// @@ -731,7 +787,7 @@ private void PrivateSetCapacity(int value) //------------------------------------------------------ #region Private Fields - private readonly Grid _owner; // owner of the collection + private Grid _owner; // owner of the collection private DefinitionBase[] _items; // storage of items private int _size; // size of the collection private int _version; // version tracks updates in the collection diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/RowDefinitionCollectionConverter.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/RowDefinitionCollectionConverter.cs new file mode 100644 index 00000000000..6665750a704 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/RowDefinitionCollectionConverter.cs @@ -0,0 +1,79 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.ComponentModel; +using System.Windows.Controls; +using System.Windows.Markup; +using System.Globalization; +using System.Text; +using MS.Internal; + +namespace System.Windows.Controls +{ + internal sealed class RowDefinitionCollectionConverter : TypeConverter + { + #region Public Methods + + /// + /// CanConvertFrom - Returns whether or not this class can convert from a given type. + /// + /// + /// bool - True if this converter can convert from the provided type, false if not. + /// + /// The ITypeDescriptorContext for this call. + /// The Type being queried for support. + public override bool CanConvertFrom(ITypeDescriptorContext typeDescriptorContext, Type sourceType) + { + return sourceType == typeof(string); + } + + /// + /// ConvertFrom - Attempt to convert to a RowDefinitionCollection from the given object. + /// + /// + /// The object which was constructed. + /// + /// + /// An ArgumentNullException is thrown if the example object is null. + /// + /// + /// An ArgumentException is thrown if the object is not null and is not a valid type, + /// or if the destinationType isn't one of the valid destination types. + /// + /// The ITypeDescriptorContext for this call. + /// The CultureInfo which is respected when converting. + /// The Thickness to convert. + public override object ConvertFrom(ITypeDescriptorContext typeDescriptorContext, CultureInfo cultureInfo, object value) + { + if (value is string input) + { + RowDefinitionCollection collection = new RowDefinitionCollection(); // Pass Grid instance + + TokenizerHelper th = new TokenizerHelper(input, cultureInfo); + while (th.NextToken()) + { + collection.Add(new RowDefinition { Height = GridLengthConverter.FromString(th.GetCurrentToken(), cultureInfo) }); + } + + return collection; + } + throw GetConvertFromException(value); + } + + /// + /// CanConvertTo - Returns whether or not this class can convert to a given type. + /// + /// + /// bool - True if this converter can convert to the provided type, false if not. + /// + /// The ITypeDescriptorContext for this call. + /// The Type being queried for support. + public override bool CanConvertTo(ITypeDescriptorContext typeDescriptorContext, Type destinationType) + { + return false; + } + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Baml2006/WpfGeneratedKnownProperties.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Baml2006/WpfGeneratedKnownProperties.cs index 2fd51dff509..725e8523548 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Baml2006/WpfGeneratedKnownProperties.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Baml2006/WpfGeneratedKnownProperties.cs @@ -6403,7 +6403,9 @@ private WpfKnownMember Create_BamlProperty_Grid_ColumnDefinitions() false // IsAttachable ); bamlMember.GetDelegate = delegate(object target) { return ((System.Windows.Controls.Grid)target).ColumnDefinitions; }; + bamlMember.SetDelegate = delegate(object target, object value) { ((System.Windows.Controls.Grid)target).ColumnDefinitions = (System.Windows.Controls.ColumnDefinitionCollection)value; }; bamlMember.IsWritePrivate = true; + bamlMember.TypeConverterType = typeof(System.Windows.Controls.ColumnDefinitionCollectionConverter); bamlMember.Freeze(); return bamlMember; } @@ -6420,7 +6422,9 @@ private WpfKnownMember Create_BamlProperty_Grid_RowDefinitions() false // IsAttachable ); bamlMember.GetDelegate = delegate(object target) { return ((System.Windows.Controls.Grid)target).RowDefinitions; }; + bamlMember.SetDelegate = delegate(object target, object value) { ((System.Windows.Controls.Grid)target).RowDefinitions = (System.Windows.Controls.RowDefinitionCollection)value; }; bamlMember.IsWritePrivate = true; + bamlMember.TypeConverterType = typeof(System.Windows.Controls.RowDefinitionCollectionConverter); bamlMember.Freeze(); return bamlMember; } diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/ref/PresentationFramework.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/ref/PresentationFramework.cs index 15b0071ed2d..3ff22611d63 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/ref/PresentationFramework.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/ref/PresentationFramework.cs @@ -3618,7 +3618,8 @@ public ColumnDefinition() { } } public sealed partial class ColumnDefinitionCollection : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IList, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList { - internal ColumnDefinitionCollection() { } + internal ColumnDefinitionCollection(Grid owner) { } + public ColumnDefinitionCollection() {} public int Count { get { throw null; } } public bool IsReadOnly { get { throw null; } } public bool IsSynchronized { get { throw null; } } @@ -5116,10 +5117,10 @@ public partial class Grid : System.Windows.Controls.Panel, System.Windows.Markup public static readonly System.Windows.DependencyProperty ShowGridLinesProperty; public Grid() { } [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Content)] - public System.Windows.Controls.ColumnDefinitionCollection ColumnDefinitions { get { throw null; } } + public System.Windows.Controls.ColumnDefinitionCollection ColumnDefinitions { get { throw null; } set { } } protected internal override System.Collections.IEnumerator LogicalChildren { get { throw null; } } [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Content)] - public System.Windows.Controls.RowDefinitionCollection RowDefinitions { get { throw null; } } + public System.Windows.Controls.RowDefinitionCollection RowDefinitions { get { throw null; } set { } } public bool ShowGridLines { get { throw null; } set { } } protected override int VisualChildrenCount { get { throw null; } } protected override System.Windows.Size ArrangeOverride(System.Windows.Size arrangeSize) { throw null; } @@ -6517,7 +6518,8 @@ public RowDefinition() { } } public sealed partial class RowDefinitionCollection : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IList, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList { - internal RowDefinitionCollection() { } + internal RowDefinitionCollection(Grid owner) { } + public RowDefinitionCollection() { } public int Count { get { throw null; } } public bool IsReadOnly { get { throw null; } } public bool IsSynchronized { get { throw null; } }