WrapPanel из Silverlight Toolkit
Создание простой тестовой программы демонстрирует некоторые интересные аспекты данной панели (WrapPanel). Для этого, откройте Visual Studio и создайте новое приложение Silverlight (Silverlight Application). Убедитесь в том, что вы добавили ссылку на Microsoft Windows Controls.dll, который прилагается c Toolkit (самое главное помнить то, где вы их расположили!)
Также вам необходимо создать пространство имен в самом начале файла Page.xaml, но Intellisence готов вам помочь в этом,
Сделав это, данный пример программы создаст WrapPanel c одной единственной кнопкой в ней - вот полный код Xaml:
<UserControl x:Class="WrapPanel.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls"
Width="800" Height="600">
<Grid x:Name="LayoutRoot" Background="White">
<controls:WrapPanel x:Name="WPanel"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Orientation="Horizontal">
<Button
x:Name="Add"
Content="Add!"
FontFamily="Georgia"
FontSize="24"
Width="Auto"
Height="Auto"
Background="#FF0000FF"
Margin="5" />
</controls:WrapPanel>
</Grid>
</UserControl>
Назначение кода, поддерживающего данную страницу, заключается в том, что когда пользователь нажимает на кнопку добавления, то выбирается один из элементов управления, созданный и добавленный к панели.
using System;
using System.Windows;
using System.Windows.Controls;
namespace WrapPanel
{
public partial class Page : UserControl
{
private Random rand = new Random();
public Page()
{
InitializeComponent();
Add.Click += new RoutedEventHandler( Add_Click );
}
Для реализации данной цели добавляется переменная экземпляра типа Random, так как существует обработчик события для кнопки добавления ("Add") созданный в Xaml.
Вся интересная работа будет проделана в обработчике события. Если вы начнете с создания элементов управления одинакового размера,
void Add_Click( object sender, RoutedEventArgs e )
{
Button b = new Button();
b.Content = DateTime.Now.ToLocalTime().ToString();
b.Width = 120;
b.Height = 35;
b.Margin = new Thickness( 5 );
this.WPanel.Children.Add( b );
}
то вы получите хорошо структурированный внешний вид, так как каждый элемент управления добавлятся до тех пор, пока не будет хватать места на строке и, следовательно, будет осуществлен перенос. (в продемонстрированном ниже примере я создал небольшие элементы управления и кнопку Add такого же размера):
Если же вы создаете другие объекты, то результат будет иным. В следующем примере я создал один из четырех типов объектов
void Add_Click( object sender, RoutedEventArgs e )
{
int choice = rand.Next( 0, 4 );
Control c;
switch ( choice )
{
case 0:
// создание кнопки
case 1:
// создание текстового поля
case 2:
// создание короткого списка
case 3:
default:
// создание элемента управления паролем (password control)
}
// установка размера шрифта
// установка ширины, высоты и отступа
// добавление элемента управления в панель
}
Тут могут появиться несколько интересных вопросов. А что, если мы установим не фиксированный размер шрифта, и что если высота будет автоматически установлена (это можно сделать программным путем, установив значение в double.Nan ).
void Add_Click( object sender, RoutedEventArgs e )
{
/*
Button b = new Button();
b.Content = DateTime.Now.ToLocalTime().ToString();
b.Width = 120;
b.Height = 35;
b.Margin = new Thickness( 5 );
this.WPanel.Children.Add( b );
*/
int choice = rand.Next( 0, 4 );
Control c;
switch ( choice )
{
case 0:
Button b = new Button();
b.Content = DateTime.Now.ToLocalTime().ToString();
c = b;
break;
case 1:
TextBox t = new TextBox();
t.Text = rand.Next(0,int.MaxValue-1).ToString();
c = t;
break;
case 2:
ItemsControl i = new ItemsControl();
i.Items.Add( "Cormac McCarthy" );
i.Items.Add( "Neal Stephenson" );
i.Items.Add( "Marcel Proust" );
i.Items.Add( "Virginia Woolfe" );
c = i;
break;
case 3:
default:
PasswordBox p = new PasswordBox();
p.Height = 35;
p.Password = "Secret";
c = p;
break;
}
c.FontSize = rand.Next( 6, 18 );
if ( c is ItemsControl )
{
c.FontSize = Math.Max( c.FontSize, 10 );
}
c.Width = Double.NaN;
c.Height = Double.NaN;
c.Margin = new System.Windows.Thickness( 5 );
this.WPanel.Children.Add( c );
}
Полученный результат интересно будет рассмотреть, хотя это и не совсем то, что мы хотели бы получить. Одним из решений будет исправление высоты кнопок, что впоследствии создаст другой интересный эффект. Сделав небольшую модификацию кода, мы можем это проверить:
if ( c is ItemsControl )
{
c.FontSize = rand.Next( 8, 18 );
c.Height = Double.NaN;
//c.FontSize = Math.Max( c.FontSize, 10 );
}
else
{
c.FontSize = 12;
c.Height = 30;
}
Это вызовет центрирование элементов управления в списке, вместо того, чтобы изменять их размеры.
Используя панели внутри других панелей, вы конечно же можете получить любой желаемый результат.