Размер элемента управления ListView или ListBox не уменьшается при наличии сложного шаблона данных, который скрывает элементы отображения на основе триггеров? - PullRequest
3 голосов
/ 02 июня 2010

У меня есть элемент ListView с DataTemplate для каждого ListViewItem, определенный следующим образом. При запуске высота ListView не сводится к элементам в представлении, что является нежелательным поведением:

<DataTemplate x:Key="LicenseItemTemplate">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"  />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Text="{Binding company}"></TextBlock>
        <Grid Grid.Row="1" Style="{StaticResource HiddenWhenNotSelectedStyle}">
            <Grid.RowDefinitions>
                <RowDefinition />
            </Grid.RowDefinitions>
            <Button Grid.Row="0">ClickIt</Button>
        </Grid>
    </Grid>
</DataTemplate>

Во втором ряду внешней сетки применяется стиль, который выглядит следующим образом. Целью стиля является предоставление подробного представления выбранного элемента данных:

<Style TargetType="{x:Type Grid}" x:Key="HiddenWhenNotSelectedStyle" >
    <Style.Triggers>
        <DataTrigger
            Binding="{Binding Path=IsSelected, 
                        RelativeSource={
                        RelativeSource 
                        Mode=FindAncestor, 
                        AncestorType={x:Type ListViewItem}
                        }
                        }" 
            Value="False">
            <Setter Property="Grid.Visibility" Value="Collapsed" />
        </DataTrigger>
        <DataTrigger
            Binding="{Binding Path=IsSelected, 
                        RelativeSource={
                        RelativeSource 
                        Mode=FindAncestor, 
                        AncestorType={x:Type ListViewItem}
                        }
                        }" 
            Value="True">
            <Setter
                Property="Grid.Visibility"
                Value="Visible"
            />
        </DataTrigger>
    </Style.Triggers>
</Style>

ListView выглядит так: Height of ListView is twice what it should be.

Желаемый вид это когда ни один из элементов не выбран: Height of ListView is collapsed to list items.

... конечно, с регулировкой высоты ListView для размещения дополнительного контента, когда вторая сетка становится видимой при выделении. Что я могу сделать, чтобы получить желаемое поведение?

Ответы [ 2 ]

15 голосов
/ 22 июня 2010

Обсуждая проблему с сотрудниками WPF на TechEd, я показал сотруднику Microsoft этот вопрос. Он был в замешательстве.

Мы загрузили инструмент, который опрашивает макеты WPF и идентифицировали контейнер как элемент «Панель виртуализации стека» в ListView.

В последующем электронном письме он написал: «Это ошибка VirtualizingStackPanel. Я открыл ошибку по этому поводу. Надеюсь, это можно исправить в будущем выпуске. Обходной путь (с помощью StackPanel) должен подойти на данный момент до тех пор, пока вам не нужен ListView для виртуализации его содержимого.

Ошибка включает в себя шаг в алгоритме Measure VSP, который запоминает самый большой размер из когда-либо обнаруженных и вынуждает все будущие вызовы Measure сообщать о размере, по крайней мере, таком большом. В вашем случае VSP первоначально измеряется до срабатывания любых триггеров, поэтому он вычисляет размер, как если бы все было видно. Когда триггеры запускают и сворачивают кнопки, алгоритм измерения вычисляет правильный (маленький) размер, но затем вынуждает результат снова быть большим. Комментарий говорит о том, что нужно избегать ненужных перекомпоновок при прокрутке, но код работает, даже если прокрутка не происходит. "

Обходной путь заключается в повторном шаблонировании ListView с этим кодом:

<ListView.ItemsPanel>
  <ItemsPanelTemplate>
    <StackPanel/>
  </ItemsPanelTemplate>
</ListView.ItemsPanel>

Это привело к тому, что поведение списка работало должным образом, но у него был недостаток, заключающийся в отсутствии возможностей управления памятью в VirtualizingStackPanel. Для моего использования это было уместно; элементы списка никогда не будут превышать 2000 или около того за один раз.

0 голосов
/ 04 июня 2010

Попробуйте добавить третью строку, определенную как

<RowDefinition Height="*" />

до <Grid.RowDefinitions> первой сетки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...