Подтвердить что ты не робот

Предотвращение расширения контроля WPF за пределы видимой области

У меня есть элемент 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>

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

4b9b3361

Ответ 1

Если вы удаляете 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 получит полосу прокрутки, когда захотите.

Ответ 2

Если предыдущий ответ не устраняет проблему, вы также можете попробовать привязать ширину, высоту вашей сетки к 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

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

Ответ 4

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

Ответ 5

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

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

Ответ 6

Почему бы просто не использовать listbox вместо itemcontrol, у которого есть встроенный scrollviewer.

Ответ 7

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

................