5

Several other questions on SO have come to the same conclusion I have -- using an ItemsControl with a DataTemplate for each item constructed to position items such that they resemble a grid is much simpler (especially to format) than using a ListView.

The code resembles:

<StackPanel Grid.IsSharedSizeScope="True">
  <!-- Header -->
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto" SharedSizeGroup="Column1" />
      <ColumnDefinition Width="Auto" SharedSizeGroup="Column2" />
    </Grid.ColumnDefinitions>
    <TextBlock Grid.Column="0" Text="Column Header 1" />
    <TextBlock Grid.Column="1" Text="Column Header 2" />
  </Grid>
  <!-- Items -->
  <ItemsControl ItemsSource="{Binding Path=Values, Mode=OneWay}">
    <ItemsControl.ItemTemplate>
      <DataTemplate>
        <Grid>
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" SharedSizeGroup="Column1" />
            <ColumnDefinition Width="Auto" SharedSizeGroup="Column2" />
          </Grid.ColumnDefinitions>
          <TextBlock Grid.Column="0" Text="{Binding ColumnProperty1}" />
          <TextBlock Grid.Column="1" Text="{Binding ColumnProperty2}" />
        </Grid>
      </DataTemplate>
    </ItemsControl.ItemTemplate>
  </ItemsControl>
</StackPanel>

The problem I'm seeing is that whenever I swap the object to which the ItemsSource is bound (it's an ObservableCollection that I replace the reference to, rather than clear and re-add), the entire 'grid' dances about for a few seconds.

Presumably it is making a few layout passes to get all the Auto-width columns to match up.

This is very distracting for my users and I'd like to get it sorted out. Has anyone else seen this?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
  • I'm having the exact same problem. Did you ever get a resolution to this? – Rick Glos Jan 19 '11 at 00:06
  • @Rick: unfortunately no, I never worked out what was going on here. It got so annoying that I just opted for fixed-width columns, though of course that came with a different set of problems. It was the lesser evil, in my case. – Drew Noakes Jan 19 '11 at 12:25
  • @Rick, were you hosting inside WinForms? It'd be good to get a repro case for this. What version of .NET are you using? I was using 3.5 (pre-SP1). – Drew Noakes Jan 19 '11 at 12:26
  • I'm using pure WPF and .NET 4.0. I'm using the Prism framework and launching a View with a backing ViewModel that I use to hold the collection of objects. Like you, I'm using a combination of a grid sitting on top of an ItemsControl and then having all the grid columns line up with SharedSizeGroup. Funny thing is, when I was mocking the data - I saw no problems. Now that I'm pulling in actual numbers, it just started doing the 'dancing/jumping'. – Rick Glos Jan 19 '11 at 16:22
  • Sorry I can't help with your problem, but your XAML code saved the day! I couldn't work out how to get a `Grid` working correctly with `ItemsControl`, so thanks :) – GONeale Jul 05 '12 at 00:04
  • Using David's answer. I set the `MinWidth` property and it all solved itself. – Ryan Amies Sep 02 '14 at 12:20

4 Answers4

1

Try set MinWidth on all your grid columns.

I have also experienced this jumpy instability. However, I got it under control by specifying a set MinWidth on all my grid columns. This seems to stabilize things when the screen is first displayed. Of course, because your columns are still linked, they grow to the max width of whatever control wins.

Also, switch off IsSharedSizeScope and try to get your grids to line up first, then switch it back on.

David
  • 429
  • 3
  • 7
1

It seems the grid's content must be a certain level of complexity before this problem is visible.

Simple TextBlock's as shown in the OP probably don't manifest the problem quite as readily because they're static size. If you throw a TextBox (not TextBlock) in a cell, then at run-time, enter enough text to cause the TextBox to auto expand the cell, you should see it start dancing wildly right away... it's well over the too-much-to-be-acceptable line. I had 7 rows in my ItemsControl.

This effectively renders the much promoted IsSharedSizeScope + ItemsControl approach to be a complete no-go, specifically for editable, TextBox oriented Grid content.

For my needs, the ListView or rather "ItemsControl + GridViewRowPresenter" approach as presented here and here is a very direct alternative and does not have any of these layout issues.

For those asking "why not a DataGrid?": the DataGrid imposes a certain approach to editing. I was willing to work through all that but wound up at a dead end with how the DataGrid mangles Validation.Error support. The little red Validation Error boxes would work fine for simple DataGridTextColumn's but for DataGridTemplateColumns (necessary to provide more than a single TextBox in one column), it would initially show the red boxes and then inconsistently hide them based on where you happened to click around the DataGrid. Upon subsequent Validation refreshes they would be completely invisible. (old example: http://code.google.com/p/itraacv2-1/source/browse/trunk/scraps/tabSponsor%20-%20before%20deactive%20rewrite.xaml, search down to "nugget: for the friggin life of me" ...)

My entire project source is online. This GridViewRowPresenter approach is represented here: http://code.google.com/p/itraacv2-1/source/browse/trunk/App/View/tabSponsor.xaml

Beej
  • 794
  • 8
  • 15
0

Unfortunately I wasn't been able to reproduce the problem with the code provided. I've tried it swapping samples of 20 up to 1000 items, and with 100 different widths inside the collection. Nothing was dancing. On huge collections (200 and higher) UI used to hang for a while and then release, showing new grid with the items provided.

HolisticElastic
  • 937
  • 8
  • 17
  • @Archimed, thanks for trying this. I've seen it happen in a few different places in my UI with as few as 5 rows, and have had to go for fixed width columns without IsSharedSizeScope to avoid the jiggling. I wonder whether it's related to hosting my elements within WinForms ElementHosts... – Drew Noakes Nov 25 '09 at 10:38
0

I had the same problem, I tried setting the MinWidth like suggested in one of the answers, but it didn't work out for me. What did help, was binding the widths from one Grid to another. I left some of the columns with the SharedSizeGroup, and nothing jumps:

<Grid Grid.IsSharedSizeScope="True">
...
    <Grid Grid.Row="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" SharedSizeGroup="Group0"/>
            <ColumnDefinition Width="Auto" SharedSizeGroup="Group1"/>
            <ColumnDefinition Width="Auto" SharedSizeGroup="Group2"/>
            <ColumnDefinition Width="Auto" x:Name="Column3"/>
            <ColumnDefinition Width="Auto" x:Name="Column4"/>
            <ColumnDefinition Width="Auto" x:Name="Column5"/>
        </Grid.ColumnDefinitions>
    ...
    </Grid>

    <ItemsControl>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" SharedSizeGroup="Group0"/>
                        <ColumnDefinition Width="Auto" SharedSizeGroup="Group1"/>
                        <ColumnDefinition Width="Auto" SharedSizeGroup="Group2"/>
                        <ColumnDefinition Width="{Binding Path=ActualWidth, ElementName=Column3}"/>
                        <ColumnDefinition Width="{Binding Path=ActualWidth, ElementName=Column4}"/>
                        <ColumnDefinition Width="{Binding Path=ActualWidth, ElementName=Column5}"/>
                    </Grid.ColumnDefinitions>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
...
</Grid>

I don't know how many columns you can leave with SharedGroupSize and how many of them need to be bound, so you can play around with the columns to see what works for you.

Andreas Koder
  • 357
  • 1
  • 3
  • 9