2016-02-26 2 views
5

У меня есть WrapPanel, и кнопки программно создаются и добавляются как дети WrapPanel. Итак, я хочу показать вертикальную полосу прокрутки, когда WrapPanel полон кнопок (детей), чтобы иметь возможность добавлять больше кнопок непрерывно.Как сделать WrapPanel, чтобы показать вертикальную полосу прокрутки, когда дети полны или без ScrollViewer

Если нам нужна полоса прокрутки, нам нужно принести ScrollViewer? Нет ли способа без ScrollViewer? То, что я хочу получить, потому что WrapPanel имеет небольшой размер, я хочу, чтобы полоса прокрутки отображалась только в случае необходимости (например, для детей).

Мой код прост, как показано ниже (WrapPanel внутри сетки и сетки внутри TabControl)

Большое спасибо всегда за совершенство.

Обновление: Я изо всех сил пытался найти решение в Интернете даже на несколько дней. И я попробовал установить WrapPanel внутри ScrollViewer. Тем не менее, хотя я устанавливаю вертикальную шину в auto, вертикальная полоса прокрутки всегда отображается, даже если WrapPanel не имеет дочерних элементов.

Кроме того, когда я намеренно делаю WrapPanel полными детей (кнопок), вертикальная полоса прокрутки ScrollViewer не обеспечивает доступность прокрутки. И кнопки в нижней строке WrapPanel показаны вырезать и больше, я не могу прокрутить вниз, чтобы увидеть за кнопкой в ​​нижней строке. Я сделал кнопки, которые можно было бы разместить вне нижней линии WrapPanel намеренно.

С или без, я хочу, чтобы вертикальная полоса прокрутки отображалась только в случае необходимости (полная детей). Кажется, очень легко сделать. Но трудно заставить его работать должным образом.

Решение: была предоставлена ​​г-на Хенка Holterman

    <DropShadowEffect/> 
       </Button.Effect> 
      </Button> 
      <WrapPanel x:Name="WrapPanelGreen" HorizontalAlignment="Left" Height="180" VerticalAlignment="Top" Width="232" UseLayoutRounding="True" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto"/> 
     </Grid> 
    </TabItem> 
</TabControl> 

А ниже мой простой код, который делает кнопку программно и добавить дочерний WrapPanel.

for (int k = 0; k < Overviews.Length; k++) 
{ 
    Button btnoverviewcontent = new Button(); 

    ToolTip tt = new ToolTip(); 
    tt.Content = "Press this button if you want to modify or delete."; 
    btnoverviewcontent.ToolTip = tt; 

    btnoverviewcontent.Cursor = Cursors.Hand; 

    SolidColorBrush mySolidColorBrush = new SolidColorBrush(); 
    mySolidColorBrush.Color = Color.FromArgb(255, 101, 173, 241); 
    btnoverviewcontent.Background = mySolidColorBrush; 

    btnoverviewcontent.Effect = new DropShadowEffect 
    { 
     Color = new Color { A = 255, R = 0, G = 0, B = 0 }, 
     Direction = 315, 
     ShadowDepth = 5, 
     Opacity = 1 
    }; 

    btnoverviewcontent.Padding = new Thickness(3, 3, 3, 3); 
    btnoverviewcontent.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Stretch; 
    TextBlock textBlock = new TextBlock() 
    { 
     Text = Overviews[k], 
     TextAlignment = TextAlignment.Left, 
     TextWrapping = TextWrapping.Wrap, 

    }; 

    btnoverviewcontent.Content = textBlock; 
    btnoverviewcontent.BorderThickness = new Thickness(0, 0, 0, 0); 
    btnoverviewcontent.FontStretch = FontStretches.UltraExpanded; 
    btnoverviewcontent.Margin = new Thickness(5, 5, 5, 5); 

    WrapPanelGreen.Children.Add(btnoverviewcontent); 
    btnoverviewcontent.Click += new RoutedEventHandler(OnOverviewClick); 
+0

Я хотел бы направить вас: http://stackoverflow.com/a/2119243/1723823 Это хорошая разбивка базовой функции WrapPanel с некоторыми комментариями о том, как реализовать прокрутку с ней. – TernaryTopiary

+0

@HenkHolterman, см. Мой обновленный вопрос. Спасибо за ваш драгоценный комментарий. –

+0

@TernaryTopiary, Большое спасибо за ваше направление. Тем не менее, я также оценил связанную страницу и в это время полностью снова. Моя проблема: дети (кнопка) сделаны программно, а размер детей различен в зависимости от их текстового содержимого. Поэтому я не могу принять второе решение. Пожалуйста, посмотрите мой обновленный вопрос. –

ответ

10

Идея в WPF является то, что каждый компонент имеет только свою работу, и если вы хотите определенное поведение, вы объединить несколько компонентов, чтобы создать представление, которое вы ищете.

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


Однако, хотя я установил verticalscroll Авто, verticalscrollbar всегда отображается, даже если WrapPanel не имеет никакого ребенка [...]

Тогда вы, кажется, с помощью ScrollViewer неправильно, или обернуть неправильный элемент. Он должен выглядеть следующим образом:

<ScrollViewer VerticalScrollBarVisibility="Auto"> 
    <WrapPanel> 
     <!-- Any number of components here --> 
    </WrapPanel> 
</ScrollViewer> 

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

Обратите внимание, что сам элемент ScrollViewer должен иметь соответствующие размеры в родительском элементе, поэтому убедитесь, что он не больше видимой области. Это также необходимо для WrapPanel (или любого другого элемента, который вы обертываете с помощью ScrollViewer), чтобы иметь автоматическую ширину и высоту. В противном случае с фиксированными размерами размеры панели не изменятся при изменении содержимого панели, и поэтому статус прокрутки не изменится.


Смотреть это полный пример с динамическим числом элементов:

<Window x:Class="WpfExampleApplication.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Height="300" Width="200"> 
    <ScrollViewer VerticalScrollBarVisibility="Auto"> 
     <WrapPanel Name="panel"> 
      <Button Click="Button_Click">Add child</Button> 
     </WrapPanel> 
    </ScrollViewer> 
</Window> 

Code-за:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     Label element = new Label() { Content = "This is some example content" }; 
     panel.Children.Add(element); 
    } 
} 
+0

Я собирался указать, что у WrapPanel уже есть компонент ScrollViewer, но у меня была игра в Visual Studio, и пришел к выводу, что даже если вы заставите ее постоянно показывать средство просмотра прокрутки (через WrapPanel XAML tag: 'ScrollViewer.VerticalScrollBarVisibility =" Visible "', на самом деле он не предлагает прокрутку для конечного пользователя. Я согласен с этим ответом. – TernaryTopiary

+1

@TernaryTopiary Прикрепленное свойство 'ScrollViewer.VerticalScrollBarVisibility' может быть прикреплено к каждому компоненту, но имеет только эффект для элементов управления, на самом деле имеющих полосу прокрутки (например, «ListView's»). Панели вообще не включают функциональные возможности прокрутки, но предлагают только различные возможности компоновки, поэтому их всегда нужно обернуть внутри 'ScrollViewer'. – poke

+0

@poke, я действительно ценю ваш драгоценный ответ. Я также пытался обернуть, как ваше предложение, но, когда я обновляюсь, дети становятся программными и установить в качестве ребенка Wrappanel. Разве это отличается от вашего предложения? Моя полоса прокрутки показывает, даже когда она не нужна и не работает, когда это необходимо ... Ох .. Боже .. Я пытался найти решение несколько дней и, наконец, попросил stackoverflow ... –