Using Grid for layout of PropertyControl

Feb 11, 2012 at 1:54 AM

Currently forms generated by PropertyControl have non-uniform label widths.

How about using Grid control with shared size groups ? For example, like this quick and dirty patch.

BTW SVN makes it really hard to track changes or contribute and that tfs-svn bridge on codeplex makes it even worse. Maybe you could consider migrating to Mercurial which is supported natively by CodePlex, it's quite easy.

Coordinator
Feb 11, 2012 at 12:35 PM

thanks for a good suggestion. I have seen the problem with non-uniform label widths, but in some situations it is nice to be able to set the MinWidth and allow the width of the labels to change. There should be a property where you can select whether to use a grid or dockpanel. It should also be possible to change the widths of the labels with a gridsplitter, and this should work on all groups (categories) at the same time. I'll add this as an issue in the issue tracker.

I see the advantages with Mercurial/Git, will consider migrating all projects I am coordinating at some point. But so far it has not been any problems with Subversion, not many contributors/forks to handle...

Feb 11, 2012 at 3:55 PM

You could also keep rows in stackpanel and wrap each row in its own grid then just unset ColumnDefinition[0].SharedSizeGroup for rows that should have different widths of label. You could even introduce multiple sizing groups (eg. short, normal, wide) to have some flexibility but still keep overall shape somewhat regular. Having a gridsplitter in such setup would be problematic though, but I don't think it's really needed - I never saw a form that allowed resizing labels by user.

The problem with SVN on CodePlex is that it's really a TFS with a broken bridge to SVN that frequently doesn't work with hg-subversion or git-svn and when it does it is really sloooow and may discourage potential contributors.

Feb 11, 2012 at 4:02 PM

BTW you should mention somewhere on main page that PropertyControl is like DataForm from Silverlight. This would make your project easier to find for people looking for WPF equivalent of that control. Also add "dataform" tag to nuget cause that's what I was looking for ;)

Coordinator
Feb 13, 2012 at 7:42 PM
Edited Feb 13, 2012 at 7:50 PM

I remember I have tried using the Grid in the past, but didn't quite get it to work the way I wanted.

PropertyGrid controls have the ability to change the width of the label column, and I would like to keep this behaviour.

I tried using the SharedSizeGroup by the following xaml:

 

      <StackPanel Grid.IsSharedSizeScope="True">
         <GroupBox Header="Group 1">
            <Grid>
               <Grid.ColumnDefinitions>
                  <ColumnDefinition Width="80" SharedSizeGroup="FirstColumn"/>
                  <ColumnDefinition Width="200" SharedSizeGroup="SecondColumn"/>
               </Grid.ColumnDefinitions>
               <TextBlock Background="Green" Text="Label1"/>
               <TextBox Grid.Column="1" Background="Red" Text="Value1"/>
               <GridSplitter Width="2" HorizontalAlignment="Right" Background="Black"/>
            </Grid>
         </GroupBox>
         <GroupBox Header="Group 2">
            <Grid>
               <Grid.ColumnDefinitions>
                  <ColumnDefinition SharedSizeGroup="FirstColumn"/>
                  <ColumnDefinition SharedSizeGroup="SecondColumn"/>
               </Grid.ColumnDefinitions>
               <TextBlock Background="Green" Text="Label2"/>
               <TextBox Grid.Column="1" Background="Red" Text="Value2"/>
               <GridSplitter Width="2" HorizontalAlignment="Right" Background="Black"/>
            </Grid>
         </GroupBox>
      </StackPanel>

 

I can't set Width of the ColumnDefinition to "*". Do you know if this is possible? 

Shouldn't it be possible to bind the ColumnDefinition widths to a common property, and avoid using SharedSizeGroup?

The GridSplitter works in the first group, but not in the second.

DataForm: Thanks, I didn't know about the DataForm control in the Silverlight toolkit. Will add tags. 

Move to hg: will try to get it done soon, I see the benefits!

Coordinator
Feb 13, 2012 at 7:43 PM

Should also make a layout option without any GroupBoxes, just a simple Grid.

Feb 13, 2012 at 10:39 PM

Not sure what exactly you are trying to achieve but you can try leaving last column out of shared sizing.

Also try experimenting with gridsplitter in its own column (ColumnDefinition.Width=Auto and ResizeBehavior=PreviousAndNext).

Anyway, I don't see a reason why anything other than Auto for labels and * for editors would be useful - that's how forms should look IMHO (and how they usually look).

You can bind all ColumnDefinition.Widths to common property and calculate it manually but that wouldn't achieve anything that isn't possible with shared size groups and min/max widths on labels.

BTW. If you put each property (row) inside it's own grid stacked vertically, then you can bind SharedSizeGroup of all first columns to some common property on PropertyControl like SharedSizeLabels with converter from bool to column group name. This way when SharedSizeLabels=true everything is uniform, otherwise existing behavior is preserved. Unfortunately I left the code on my work machine, but I'll post it tomorrow. You can also disable shared sizing in per-row.

Coordinator
Feb 14, 2012 at 5:03 AM

Right, the last column should of course not use shared sizing :)

I am trying to test your layout suggestion with the xaml code, here is the updated version (there is still some strange behaviour with the grid splitters):

   <StackPanel Grid.IsSharedSizeScope="True">
      <GroupBox Header="Group 1">
         <Grid>
            <Grid.ColumnDefinitions>
               <ColumnDefinition
                  MaxWidth="160"
                  MinWidth="80"
                  Width="Auto"
                  SharedSizeGroup="FirstColumn"/>
               <ColumnDefinition Width="2"/>
               <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <TextBlock Background="Green" Text="Label1"/>
            <TextBox Grid.Column="2" Background="Red" Text="Value1"/>
            <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" ResizeBehavior="PreviousAndNext" Background="Black"/>
         </Grid>
      </GroupBox>
      <GroupBox Header="Group 2">
         <Grid>
            <Grid.ColumnDefinitions>
               <ColumnDefinition
                  MaxWidth="160"
                  MinWidth="80"
                  Width="Auto"
                  SharedSizeGroup="FirstColumn"/>
               <ColumnDefinition Width="2"/>
               <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <TextBlock Background="Green" Text="Long label2"/>
            <TextBox Grid.Column="2" Background="Red" Text="Value2"/>
            <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" ResizeBehavior="PreviousAndNext" Background="Black"/>
         </Grid>
      </GroupBox>
   </StackPanel>

Feb 14, 2012 at 9:42 AM

Yes I have noticed that gridsplitter has a tendency to get stuck sometimes.

Here is the suggestion I made above in a form of a patch against trunk.

Coordinator
Feb 15, 2012 at 8:40 AM

Thanks, I will check this patch soon. The source control has now been changed to Mercurial.

Coordinator
Feb 16, 2012 at 5:42 AM

I applied the patch with some modifications (added LabelWidthSharing and EnableLabelWidthResizing properties, not using binding on LabelWidthSharing - since this probably never is frequently changed).