Добавление дочерних элементов управления в Stackpanel WPF С#

Я очень много нового в WPF.

У меня очень простая проблема.

У меня есть стековая панель spTerminalBox.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="300"/>
        <ColumnDefinition Width="881*"/>
        <ColumnDefinition Width="11*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="156"/>
        <RowDefinition Height="371*"/>
    </Grid.RowDefinitions>
    <my:WindowHeader x:Name="title" Title="Internet Cafe management software (ICM)"   CloseClicked="window_CloseClicked"   VerticalAlignment="Top" Margin="0,-1,0,0" Grid.ColumnSpan="3" />
    <StackPanel Name ="spTerminalBox" Grid.Column="1" Grid.Row="1" Orientation="Horizontal" Margin="10,10,10,20"/>
</Grid>

Моя структура xaml такова.

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

Как это сделать?

Ответ 1

XAML:

<Window x:Class="WpfTestBench.PanelSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="PanelSample" Height="300" Width="300">
    <Grid>
        <WrapPanel Name="MyPanel" />
    </Grid>
</Window>

Codebehind:

using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;

namespace WpfTestBench
{
    public partial class PanelSample
    {
        public PanelSample()
        {
            InitializeComponent();

            for (var i = 0; i < 5; i++)
            {
                MyPanel.Children.Add(new Rectangle
                {
                    Width = 100,
                    Height = 20,
                    StrokeThickness = 1,
                    Stroke = new SolidColorBrush(Colors.Black),
                    Margin = new Thickness(5)
                });
            }
        }
    }
}

Результат выполнения:

WideNarrow

Ответ 2

вы должны использовать WrapPanel для своих требований.

Ответ 3

Оберните StackPanel в ScrollViewer и вызовите ScrollIntoView() только что добавленного элемента.

Ответ 4

Вместо использования StackPanel и добавления UserControls используйте ListBox, который вы привяжите к ObservableCollection. "ObservableCollection" будет уведомлять ListBox, когда элементы будут добавлены/удалены.
Измените ListBox.ItemsPanel как Wrappanel вместо StackPanel

взято из http://wpftutorial.net/
"The wrap panel is similar to the StackPanel but it does not just stack all child elements to one row, it wraps them to new lines if no space is left. The Orientation can be set to Horizontal or Vertical."

вы, Xaml, должны выглядеть так:

<ListBox  x:Name="MyListBox"
          ItemsSource="{Binding Source={StaticResource UserControlsObservableCollection}}"                                  
          HorizontalContentAlignment="Stretch"
          ScrollViewer.HorizontalScrollBarVisibility="Disabled"
          ScrollViewer.VerticalScrollBarVisibility="Disabled" >
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
              <WrapPanel />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

Ответ 5

будет лучше использовать для вашего случая, у него есть прикрепленное свойство, готовое для этого, но StackPanel будет работать в FIFO

DockPanel

for example 

            Button btn = new Button();
            DockPanel.SetDock(btn,Dock.Bottom);
            dockPanelTerminalBox.Children.Add(btn); 

но если вы хотите просто использовать это в своем коде за

spTerminalBox.Children.Add("yourControl");