Open rizamarhaban opened 4 years ago
This looks like a duplicate of #673
@japf It's not. Issue #673 is about simplifying the syntax used to define rows and columns:
Ability for rows and columns to be defined as a collection or list of values (using CreateFromString attribute)
Adding a name to a row/columm so we can use that name to reference a row/column instead of its index in the row/column collection is purposefully not part of that proposal. This issue here proposes adding that naming capability to rows/columns so that changes like inserting new rows/columns in the grid don't require changing the indices in affected <Control Grid.Row/Column=.../>
XAML.
The example you see in this proposal shows how naming rows/columns could work alongside the new syntax proposed in #673.
This issue is part of the very broad Make Grid Better proposal.
The name should change to reflect to focus on the unique proposal here. Naming Grid Rows and Columns for Simplified Syntax.
Yes, the name of the proposal should be changed. An example name could be: "Able to refer to rows / columns by name" (based on the Make Grid Better proposal).
It does look very similar to #673 except for the naming aspect. I like the @mdtauk 's idea of scoping this down to just the naming and keep the rest of the discussions in the other proposal. Thanks.
Since issue #673 has been greenlighted based on my understanding the idea
Allowing to add variable for each row and column index definition value. I propose to use a colon simply [variable name]:[value]
should be kept in this proposal (i.e. how to name a row/column with the new compact syntax).
@rizamarhaban Right now it seems to me you are proposing naming rows/columns ony when using the new compact syntax. What about adding this capability to the current Grid API/syntax? Should we have a separate issue for that? Do we even need to add naming capability to the current Grid API/syntax or will this be a feature exclusive to the new compact defintion syntax?
@rizamarhaban Thank you for filing the proposal. Can you please update the proposal and scope it down to just naming rows and columns (on top of what is proposed in #673 ) ?
@Felix-Dev @ranjeshj I include the syntax simplification like similar in #673 because has not been implemented and I have the same idea but with adding variables or naming row/column. I also add the new attribute Grid.RowColumn which is not the same with #673. I can update the title to reflect this, but this is not just simply inlining the row/col values.
@rizamarhaban You seem to propose two new features here - naming rows/columns and a new API for a compact row/column specification (Grid.RowColumn). The naming feature alone should be in its own proposal as suggested by @ranjeshj as it raises a couple of questions worth thinking about. (I.e. will it only work for the new compact syntax or also for the current grid syntax? If the latter, do we need to add new API and how would that look like?)
Given this, it would be best if you would split this proposal into two proposals...one covering the new naming feature and the other one proposing the new Grid.RowColumn API.
@Felix-Dev yes it's 2 new features and will add into the scope.
Should also be an option name:
<Grid ColumnDefinitions="1* b:2* Auto d:* 300"
RowDefinitions="1* Auto i:25 14 20">
</Grid>
@michael-hawker yes it is. In the example, if there is no variable name then fallback to indexes. We can use both indexes or the name if assigned.
@rizamarhaban Please answer the following questions: Will your naming proposal only work for the new compact syntax or also for the current grid syntax? If the latter, do we need to add new API and how would that look like?
The way I'm reading your current naming proposal you are proposing a feature which would make the current Grid syntax and the new compact syntax in issue #673 no longer equivalent. In other words, you want to add a feature available to the new compaxt syntax only. Issue #673 only proposes a syntax simplication, it does not add new features exclusive to the new compact syntax. Your current proposal would change that and thus this should be discussed.
@Felix-Dev
Will your naming proposal only work for the new compact syntax or also for the current grid syntax? If the latter, do we need to add new API and how would that look like?
Technically, this can be use for the current syntax as well. Alternatively, both new compact syntax and current syntax may implement this. Meaning, there will be new API requirements. As this won't break any changes of the current XAML, need to discuss what the API may look like. I will update the Example to include the current syntax as well.
@rizamarhaban Thanks for updating 🙂
This looks like a very very good idea. This way, when re-arranging rows/columns, it will be very easy.
One thing that comes to mind is adding a grid splitter (which takes one row or column) <- this right now requires me manually editing the xaml and hope I don't miss anything. With this proposal, I would not need any xaml editing.
Also, very useful when you need to quickly re-arrange rows (you realize some low row needs to come to the top or so).
Thanks for filing this, @rizamarhaban! Sorry I am just getting around to seeing it. The naming idea (as others mentioned) was brought up in the initial Make Grid Better proposal #54, and it seems like a popular want to help deal with large numbers of rows and columns. I like that your proposal accounts for making sure that it works with the old syntax and the new, compact syntax - we don't want to cause breaking changes or leave pure UWP (non-WinUI 3) apps out of the feature.
In terms of the RowColumn attribute, I was wondering what the motivation was. Is it just a shorter way of assigning placement to elements, instead of writing Grid.Column="0" and Grid.Row="0"? To me, this seems like it would take almost the same amount of effort to write and I'm not sold that it's something that needs to be implemented... feel free to prove me wrong! Would love to hear more arguments for this.
One more detail question about your proposed changes: I'm wondering what happens behind the scenes when a name for a row is omitted, as shown here with Auto
:
<Grid ColumnDefinitions="a:1* b:2* c:Auto d:* e:300"
RowDefinitions="a:1* Auto i:25 whatever:14 k:20">
</Grid>
You use the index number to refer to it here:
<TextBlock Grid.Row="1" Grid.Column="c" /> <!-- using index number on Row -->
Does this mean that even if a row/column does have a name, you can still use its index to refer to it? I assume that the Name property for a RowDefinition or ColumnDefinition is a string. Would the index get converted into a string and used for the Name property, or would it just be the general rule that rows/columns can be referred to by their index or Name? If so, that leads to more questions about accessing rows and columns in the code-behind...
Maybe I'm thinking too far ahead, but let me know if anyone has thoughts on these points :)
@anawishnoff I could see the Row/Column attached properties still being defined as integers, it'd just be the XAML TypeConverter that knows how to do the magic with the string to look-up an index. Then there'd be a method like GetIndexFromName(string)
on Grid that's used in that function as well as for code-behind use?
@anawishnoff the motivation is:
<!-- ... -->
for rows or columns for easy searching. Especially on a large Grid.Grid.RowColumn
for short.<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition Height="25" />
<RowDefinition />
</Grid.ColumnDefinitions>
</Grid>
In the above example, if we reorder the definition of index 0 and 3, it doesn't have any changes on the UI. However, index 1 and 2 might change the UI because height different. However, if we can do like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition x:Name="a" />
<RowDefinition Height="Auto" />
<RowDefinition Height="25" />
<RowDefinition x:Name="b" />
</Grid.ColumnDefinitions>
</Grid>
and I switch the definitions to be like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition x:Name="b" />
<RowDefinition Height="Auto" />
<RowDefinition Height="25" />
<RowDefinition x:Name="a" />
</Grid.ColumnDefinitions>
</Grid>
Then all the UI which uses Grid.Row="a" or Grid.Row="b" will switch as well. Nice right. No need to replace the index number from 3 to 0 and 0 to 3. Unless they did not define naming like on row index 1 and 2. That will need to follow the current existing rule on Grid index. Also, if we need to do like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition x:Name="a" />
<RowDefinition Height="Auto" />
<RowDefinition x:Name="c" Height="Auto" />
<RowDefinition Height="25" />
<RowDefinition x:Name="b" />
</Grid.ColumnDefinitions>
</Grid>
There will be no changes on Grid.Row 'a' and 'b' elements. However, we need to replace the index number row '3' as '4' to adjust the Grid.Row element. :) That's the motivation. Let's make it simple like this, e.g.:
<!-- Index: 0 1 2 -->
<Grid RowDefinitions="awesome:Auto lovely:Auto *">
<TextBlock Grid.RowColumn="awesome,0" Text="Awesome..." />
<TextBlock Grid.RowColumn="lovely,0" Text="Lovely..." />
<StackPanel Grid.RowColumn="2,0" />
</Grid>
This will show Awesome and Lovely on each row. And someday we can just switch the definition to be like this:
<!-- Index: 0 1 2 -->
<Grid RowDefinitions="lovely:Auto awesome:Auto *">
<TextBlock Grid.RowColumn="awesome,0" Text="Awesome..." />
<TextBlock Grid.RowColumn="lovely,0" Text="Lovely..." />
<StackPanel Grid.RowColumn="2,0" />
</Grid>
The UI changes to show Lovely and Awesome on each row. And there you go.
@michael-hawker @rizamarhaban
I definitely think it would be necessary to have a GetIndexFromName() method here, which makes things a bit easier. Thank you for all of the examples - it definitely clears up how helpful named rows and columns would be in terms of switching around the Grid and interacting with it.
The unnamed row/column scenario is a bit messy, but it would be the developer's prerogative as to whether or not they want to name their rows/columns for more ease.
I'm gonna push just a little bit harder on the Grid.RowColumn attribute 😊: I do get what you're saying that it may make refactoring easier for large grids, although for searching within a grid I feel like searching for individual named rows and columns would be similarly easy. Is that enough of a reason to implement a whole other attribute into Grid which already has such a large API? Do you know of any other Xaml controls which implement similar attributes? Would need some more convincing on this one.
Yeah, I don't see as much of a need for RowColumn
, especially as I'm sure @mrlacey could come up with some amazing helper as part of his extensions for moving items around in a Grid for refactoring... 😋
@anawishnoff @michael-hawker yeah, fair enough.
The RowColumn
idea seems like it would be easy to try out with a custom attached property. It feels like the kind of thing that could/should be tried out before a lot of time is spent on incorporating it into something larger (like WinUI.)
After trying it out, it would be good to get feedback on what it's like to use, how beneficial it is, whether new developers (unfamiliar with the syntax) find it easy to understand or confusing because it's too different to what they already know, etc.
A good point is that inline syntax will enable to configure the grid using Style Setters:
<Setter Property="ColumnDefinitions" Value="*,*,*" />
Suggesting that the syntax be expanded to include a trailing >=n and/or <=n representing MinHeight and MaxHeight for each row/column specifier. I have done this successfully in my own version of this feature.
Another suggestion, if it is not too much of a distraction, is to allow just A as a short form of Auto. Hence we could have, for example, RowDefinitions="A, A>=24, A, *, A, 2*<=300".
P.S. personally I believe the commas should be required, not optional.
Proposal: Naming Grid Rows/Columns on Simplified Inline Syntax and Grid.RowColumn
Summary
This proposal is to add feature to simplify the syntax of
Grid
Rows, Columns and its implementation:Grid
Rows and Columns definitions inline. Can use comma or space as the delimeter.[variable name]:[value]
. See example below on this.Grid.RowColumn
besidesGrid.Row
andGrid.Column
.Rationale
RowDefinition
andColumnDefinition
.Scope
RowDefinitions
andColumnDefinitions
of GridGrid.RowColumn
for the Row/Column of GridExample
Define Grid Rows and Columns for Current Syntax
Define Grid Rows and Columns Inline compact syntax (NEW API)
Notes: the
RowDefinition
ofAuto
above does not have naming. This will fallback to index number 1.Grid Row and Column Implementation (NEW API)
When we need to reference on which rows and column, we just do:
If no variable name, simply fallback to use index number.
New Attribute
Grid.RowColumn
(NEW API)This to simplify without the assignment for the row and column:
With these hopefully easy to refactor as well. However, this will also allow to use index numbers, i.e.,