This will be done best with an ItemsControl
, and yes, I would render each seat as a Rectangle
so you can get all the mouse and selection events (since I imagine you want users to be able to select seats). If you want less overhead, you could step down to using rectangle geometries, but for 200 seats that are not moving, the overhead of a Rectangle
will not be bad.
First, I would create some code-behind to store information about each seat. I am not sure what seat data you want in your model, but I think at the very least you would like to see a seat number. You could add other data such as an occupied or reserved status for the seat, but for now I have kept it simple:
public partial class SeatingArea : UserControl
{
public ObservableCollection<int> Seats { get; private set; }
public SeatingArea()
{
Seats = new ObservableCollection<int>();
for (int i = 1; i <= 200; i++)
Seats.Add(i);
InitializeComponent();
}
}
Now for the XAML, you need to create an ItemsControl
and set its ItemsSource
to the seats collection. Then, using the ItemTemplate
property, you can control how each seat will be rendered. In this case, it is simple: we will draw a single rectangle and overlay some text containing the number on top of the rectangle. Finally, we need the seats to be arranged in a square, so we set our ItemsPanel
property to be a WrapPanel
. This ensures that the seats will be arranged in rows. For the finishing touches, I have added a Trigger
that will give seats a red glow when they are moused over. You can imagine many other triggers that would not be difficult to add.
<UserControl x:Class="TestWpfApplication.SeatingArea"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Beige"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<StackPanel>
<TextBlock HorizontalAlignment="Center" Text="SEATING CHART" FontSize="24" Margin="0,10"/>
<ItemsControl ItemsSource="{Binding Seats}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Rectangle x:Name="Seat" Width="25" Height="25" Stroke="Black" Fill="Green" Margin="1,2"/>
<TextBlock Text="{Binding}" TextAlignment="Center" VerticalAlignment="Center"
Foreground="White" FontWeight="Bold"/>
</Grid>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Seat" Property="Effect">
<Setter.Value>
<DropShadowEffect Color="Red" ShadowDepth="0"/>
</Setter.Value>
</Setter>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Height="300" Width="550"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
With all of this, here is the resulting (super simple) seating chart:
