-
Notifications
You must be signed in to change notification settings - Fork 0
Grid Shorthand Syntax Implementation #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release/9.0
Are you sure you want to change the base?
Changes from 2 commits
7a5aa07
61376b0
5cab537
f14d5e3
56975ef
f4f03c8
3af704d
bd9984b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| // 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 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if it makes sense to have create base type converter for code shared between Rows and Columns There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They don't really have any properties in common, the code would have to be split anyway even if it was a single converter. And I would rather have two standalone converters than one relying on type descriptor to figure out what the converter should produce.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with @miloush here, there is very less commonality between the two properties and we would need to bifurcate the code to handle the properties. |
||
| { | ||
| #region Public Methods | ||
|
|
||
| /// <summary> | ||
| /// CanConvertFrom - Returns whether or not this class can convert from a given type. | ||
| /// </summary> | ||
| /// <returns> | ||
| /// bool - True if this converter can convert from the provided type, false if not. | ||
| /// </returns> | ||
| /// <param name="typeDescriptorContext"> The ITypeDescriptorContext for this call. </param> | ||
| /// <param name="sourceType"> The Type being queried for support. </param> | ||
| public override bool CanConvertFrom(ITypeDescriptorContext typeDescriptorContext, Type sourceType) | ||
| { | ||
| return sourceType == typeof(string); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// CanConvertTo - Returns whether or not this class can convert to a given type. | ||
| /// </summary> | ||
| /// <returns> | ||
| /// bool - True if this converter can convert to the provided type, false if not. | ||
| /// </returns> | ||
| /// <param name="typeDescriptorContext"> The ITypeDescriptorContext for this call. </param> | ||
| /// <param name="destinationType"> The Type being queried for support. </param> | ||
| public override bool CanConvertTo(ITypeDescriptorContext typeDescriptorContext, Type destinationType) | ||
| { | ||
| return destinationType == typeof(string); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// ConvertFrom - Attempt to convert to a ColumnDefinitionCollection from the given object. | ||
| /// </summary> | ||
| /// <returns> | ||
| /// The object which was constructed. | ||
| /// </returns> | ||
| /// <exception cref="ArgumentNullException"> | ||
| /// An ArgumentNullException is thrown if the example object is null. | ||
| /// </exception> | ||
| /// <param name="typeDescriptorContext"> The ITypeDescriptorContext for this call. </param> | ||
| /// <param name="cultureInfo"> The CultureInfo which is respected when converting. </param> | ||
| /// <param name="value"> The Thickness to convert. </param> | ||
| 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); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// ConvertTo - Attempt to convert a ColumnDefinitionCollection to the given type | ||
| /// </summary> | ||
| /// <returns> | ||
| /// The object which was constructed. | ||
| /// </returns> | ||
| /// <exception cref="ArgumentNullException"> | ||
| /// An ArgumentNullException is thrown if the example object is null. | ||
| /// </exception> | ||
| /// <param name="typeDescriptorContext"> The ITypeDescriptorContext for this call. </param> | ||
| /// <param name="cultureInfo"> The CultureInfo which is respected when converting. </param> | ||
| /// <param name="value"> The ColumnDefinitionCollection to convert. </param> | ||
| /// <param name="destinationType">The type to which to convert the ColumnDefinitionCollection instance. </param> | ||
| public override object ConvertTo(ITypeDescriptorContext typeDescriptorContext, CultureInfo cultureInfo, object value, Type destinationType) | ||
| { | ||
| ArgumentNullException.ThrowIfNull(value); | ||
| ArgumentNullException.ThrowIfNull(destinationType); | ||
| if (destinationType == typeof(string) && value is ColumnDefinitionCollection columnDefinitions) | ||
| { | ||
| char listSeparator = TokenizerHelper.GetNumericListSeparator(cultureInfo); | ||
| StringBuilder sb = new StringBuilder(5 * columnDefinitions.Count); | ||
|
|
||
| for (int i = 0; i < columnDefinitions.Count; i++) | ||
| { | ||
| if (i > 0) | ||
| { | ||
| sb.Append(listSeparator); | ||
| } | ||
| sb.Append(GridLengthConverter.ToString(columnDefinitions[i].Width, cultureInfo)); | ||
| } | ||
|
|
||
| return sb.ToString(); | ||
| } | ||
|
|
||
| throw GetConvertToException(value, destinationType); | ||
| } | ||
|
|
||
| #endregion Public Methods | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -272,6 +272,7 @@ public bool ShowGridLines | |
| /// <summary> | ||
| /// Returns a ColumnDefinitionCollection of column definitions. | ||
| /// </summary> | ||
| [TypeConverter(typeof(ColumnDefinitionCollectionConverter))] | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason why type converter is applied to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would find that a higher risk, as it would affect uses outside of the Grid (and would get returned by TypeDescriptor). The main reason I would be reluctant to do so is because the converter does not really support converting the whole collection. It supports only quite a narrow albeit common case where properties like MinWidth, MaxWidth, Offset or SharedSizeGroup are not set. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is also a discussion that for that reason, the converter might only support conversion from string, not to string. (And type converter applied to a property was an important distinguishing factor for the XAML parser to allow manipulating collections using attribute, though with public setter we have departed from that requirement.) |
||
| [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] | ||
| public ColumnDefinitionCollection ColumnDefinitions | ||
| { | ||
|
|
@@ -282,11 +283,26 @@ public ColumnDefinitionCollection ColumnDefinitions | |
|
|
||
| return (_data.ColumnDefinitions); | ||
| } | ||
| set | ||
| { | ||
| if (value?.Owner is not null) | ||
himgoyalmicro marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| throw new ArgumentException(SR.Format(SR.GridCollection_InOtherCollection, "value", "ColumnDefinitionCollection")); | ||
| } | ||
| _data ??= new ExtendedData(); | ||
| _data.ColumnDefinitions?.Clear(); | ||
dipeshmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (value is not null) | ||
| { | ||
| value.Owner = this; | ||
| _data.ColumnDefinitions = value; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Returns a RowDefinitionCollection of row definitions. | ||
| /// </summary> | ||
| [TypeConverter(typeof(RowDefinitionCollectionConverter))] | ||
| [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] | ||
| public RowDefinitionCollection RowDefinitions | ||
| { | ||
|
|
@@ -297,6 +313,25 @@ public RowDefinitionCollection RowDefinitions | |
|
|
||
| return (_data.RowDefinitions); | ||
| } | ||
| set | ||
| { | ||
| _data ??= new ExtendedData(); | ||
| _data.RowDefinitions ??= new RowDefinitionCollection(this); | ||
| _data.RowDefinitions.Clear(); | ||
|
||
| if (value == null) | ||
|
||
| { | ||
| return; | ||
| } | ||
| foreach (RowDefinition rowDef in value) | ||
| { | ||
| if (rowDef.Parent != null) | ||
|
||
| { | ||
| throw new ArgumentException(SR.Format(SR.GridCollection_InOtherCollection, "value", "RowDefinitionCollection")); | ||
| } | ||
| rowDef.Index = -1; | ||
| _data.RowDefinitions.Add(rowDef); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #endregion Public Properties | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.