Предотвратить расширение контроля WPF за пределы видимой области - PullRequest
23 голосов
/ 23 декабря 2010

У меня есть ItemsControl в моем пользовательском элементе управления со средством просмотра прокрутки вокруг него, когда он становится слишком большим (Слишком большое существо контента больше, чем видимая область UserControl).Проблема в том, что сетка, в которой она находится, просто продолжает расширяться, так что средство просмотра прокрутки никогда не включается (если я не укажу точную высоту для сетки).См. Код ниже и спасибо заранее.

 <UserControl  x:Class="BusinessObjectCreationWizard.View.TableSelectionPageView"
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <GroupBox FontWeight="Bold" Height="300px"
              Header="Tables"
              Padding="2">

        <ScrollViewer>

            <ItemsControl FontWeight="Normal" 
                          ItemsSource="{Binding Path=AvailableTables}">
                <ItemsControl.ItemTemplate>

                    <DataTemplate>              
                        <CheckBox Content="{Binding Path=DisplayName}"
                                  IsChecked="{Binding Path=IsSelected}"
                                  Margin="2,3.5" /> 
                    </DataTemplate> 
                </ItemsControl.ItemTemplate> 
            </ItemsControl>
        </ScrollViewer>
    </GroupBox>
</UserControl>

Этот пользовательский элемент управления загружен здесь

<Border Background="White" Grid.Column="1" Grid.Row="0">
        <HeaderedContentControl Content="{Binding Path=CurrentPage}" 
                                Header="{Binding Path=CurrentPage.DisplayName}" />
</Border>

Я не хотел бы указывать высоту.

Ответы [ 7 ]

28 голосов
/ 04 января 2011

Если вы удалите Height из вашего GroupBox (что, насколько я понимаю, это то, что вы хотите сделать), тогда он заполнит свой контейнер, если только нет панели вверх по течению, которая налагает свои собственные правила определения размера.

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

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <GroupBox FontWeight="Bold" Header="Tables" Padding="2">
        <ScrollViewer>
            <ItemsControl FontWeight="Normal">
                <TextBlock>Foo</TextBlock>
                <TextBlock>Bar</TextBlock>
                <TextBlock>Baz</TextBlock>
            </ItemsControl>
        </ScrollViewer>
    </GroupBox>
</Window>

Запустите его, и вы увидите, что содержание действительно соответствует размеру окна, а полоса прокрутки включается только тогда, когда окно становится слишком маленьким, чтобы увидеть все три элемента. Я считаю, что это то, что вы хотите.

Таким образом, проблема, скорее всего, связана с одной из родительских панелей, которую вы не видите в своем примере XAML. Проблема, которую вы описываете, может возникнуть, если ваш GroupBox появляется внутри StackPanel:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <StackPanel>
        <GroupBox FontWeight="Bold" Header="Tables" Padding="2">
            <ScrollViewer>
                <ItemsControl FontWeight="Normal">
                    <TextBlock>Foo</TextBlock>
                    <TextBlock>Bar</TextBlock>
                    <TextBlock>Baz</TextBlock>
                </ItemsControl>
            </ScrollViewer>
        </GroupBox>
    </StackPanel>
</Window>

Теперь GroupBox появляется в верхней части окна, размер которого точно соответствует его содержимому. Если вы достаточно уменьшите окно, GroupBox будет обрезан - потому что он имеет размер, соответствующий его содержимому, а не контейнеру. Это похоже на проблему, которую вы описываете.

Причина в том, что StackPanel спрашивает своих детей, какова их идеальная высота (в зависимости от их содержимого), и использует эту высоту. Без StackPanel (или чего-то подобного) по умолчанию учитывается значение VerticalAlignment элемента управления, и если для него установлено значение Stretch по умолчанию, элемент управления растягивается, чтобы заполнить его родительский элемент. Это означает, что он не будет выше своего родителя, что звучит так, как вы хотите.

Решение: удалите StackPanel (или что-либо еще, что вызывает у вас проблемы) и используйте что-то еще. В зависимости от того, чего вы пытаетесь достичь, вам может повезти с DockPanel или Grid. Трудно сказать, не зная больше о вашем макете.

Редактировать: Хорошо, похоже, проблема действительно в HeaderedContentControl родителе - но не напрямую. HeaderedContentControl не является панелью, поэтому он не имеет собственной разметки (и его потомок, GroupBox, не имеет такой же проблемы). Проблема в шаблоне по умолчанию, который включает в себя StackPanel. Хорошей новостью является то, что вы можете использовать другой шаблон, скажем, с DockPanel:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <HeaderedContentControl>
    <HeaderedContentControl.Style>
      <Style TargetType="{x:Type HeaderedContentControl}">
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="{x:Type HeaderedContentControl}">
              <DockPanel>
                <ContentPresenter ContentSource="Header" DockPanel.Dock="Top"/>
                <ContentPresenter/>
              </DockPanel>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style>
    </HeaderedContentControl.Style>
    <GroupBox FontWeight="Bold" Header="Tables" Padding="2">
      <ScrollViewer>
        <ItemsControl FontWeight="Normal">
          <TextBlock>Foo</TextBlock>
          <TextBlock>Bar</TextBlock>
          <TextBlock>Baz</TextBlock>
        </ItemsControl>
      </ScrollViewer>
    </GroupBox>
  </HeaderedContentControl>
</Window>

Если вы пропустите часть <HeaderedContentControl.Style>, это воспроизведет вашу проблему; но при наличии стиля он позволяет GroupBox заполнить свой контейнер, поэтому ScrollViewer получит полосу прокрутки, когда вы этого захотите.

10 голосов
/ 23 декабря 2010

Если предыдущий ответ не устранил проблему, вы также можете попробовать связать ширину, высоту вашей сетки с ActualWidth, ActualHeight вашего родительского UserControl. Что-то вроде:

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication.UserControl1"
x:Name="UserControl">
<Grid Height="{Binding ElementName=UserControl, Path=ActualHeight}"
      Width="{Binding ElementName=UserControl, Path=ActualWidth}" />

В этом случае вы не устанавливаете явную ширину и высоту, но ограничиваете ширину / высоту сетки ограничениями UserControl, в котором он находится.

3 голосов
/ 16 октября 2015

У меня была такая же проблема, после прочтения этого ответа я заменил все StackPanels на Grids в UserControl.Это решило проблему с полосой прокрутки.

1 голос
/ 10 января 2017

Они разные. Если вы не хотите, чтобы элементы выбирались, не используйте ListBox. Он будет тяжелее и будет отменять выбор при каждом нажатии пользователем на запись. Просто поместите ItemsControl в ScrollViewer

0 голосов
/ 04 апреля 2019

У меня была та же проблема с ListBox, он не расширялся, и просмотрщик прокрутки не появлялся. Я решил это следующим образом:

 <UserControl x:Class="TesteView" 
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
      <Grid MaxHeight="710">
      ....
      ....
      <StackPanel>
         <ListBox  MaxHeight="515" 
            ScrollViewer.HorizontalScrollBarVisibility="Hidden" 
            ScrollViewer.VerticalScrollBarVisibility="Auto" 
            ItemsSource="{Binding Path=Teste,Mode=TwoWay}">
            ....
            ....
        </ListBox>
     </StackPanel>
    </Grid>
   </UserControl>
0 голосов
/ 24 декабря 2010

Почему бы просто не использовать список вместо элемента управления, который имеет встроенный просмотрщик прокрутки.

0 голосов
/ 23 декабря 2010

Попробуйте полностью удалить сетку и установить HorizontalAlignment и VerticalAlignment непосредственно в GroupBox.Если у макета есть только один дочерний элемент, он часто избыточен ... это справедливо в вашем случае.

Если это не работает ... каков родитель вашего элемента управления сеткой?

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