Drawing Ellipse Line/PolyLine with a double - wpf

I have been working with this example to draw bar graph. The bar part is done and it represents the volume/quantity in a transaction. It's an associated price in range 20 - 30. What I want now is to draw points to represent price associated with volumes and connect those points. Two changes I've made in EDIT part of the linked example (1) removed the TextBlock from the DataTemplate of ItemsControl and added an Ellipse instead and (2) edited the canvas to add price/volume axis label. Here's how it looks like now:
How to add those Ellipse in right position and connect those with Line/PolyLine?
EDIT
Here's what I've now in ItemsControl:
<ItemsControl ScrollViewer.CanContentScroll="True"
Height="135"
ItemsSource="{Binding RectCollection}"
Margin="50 0 50 0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Canvas Width="20">
<Canvas.LayoutTransform>
<ScaleTransform ScaleY="-1"/>
</Canvas.LayoutTransform>
<Rectangle Width="18"
Margin="0 0 2 0"
VerticalAlignment="Bottom"
Opacity=".5" Fill="LightGray">
<Rectangle.Height>
<MultiBinding Converter="{StaticResource VConverter}">
<Binding Path="ActualHeight"
RelativeSource="{RelativeSource AncestorType=ItemsControl}"/>
<Binding Path="DataContext.HighestPoint"
RelativeSource="{RelativeSource AncestorType=ItemsControl}"/>
<Binding Path="Volume"/>
</MultiBinding>
</Rectangle.Height>
</Rectangle>
<Line Stroke="DarkGreen" StrokeThickness="1"
X1="10" X2="30"
Y2="{Binding PreviousPrice, Converter={StaticResource PConverter}}"
Y1="{Binding CurrentPrice, Converter={StaticResource PConverter}}">
<Line.Style>
<Style TargetType="Line">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=PreviousPrice}" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Line.Style>
</Line>
<Ellipse Fill="Red" Width="6" Height="6" Margin="-3" Canvas.Left="10"
Canvas.Top="{Binding CurrentPrice, Converter={StaticResource PConverter}}"/>
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer
VerticalScrollBarVisibility="Hidden"
Background="{TemplateBinding Panel.Background}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
oh! I forgot to add those ValueConverters, here're those:
public class VolumeConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var height = (double)values[0];
var higest = (double)values[1];
var value = (double)values[2];
return value * height / higest;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class PriceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is double)) return null;
var price = (double)value;
var remainingHeight = 90;
var priceRange = 30 - 20.0;
return 45 + ((price - 20) * remainingHeight / priceRange);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
and here's how it looks like:
As suggested by #Clemens, I've to have another double?, in case where Insert(0, ... ) is used on ObservableCollection instead of Add(...) to add the last item in first place and removed the AternationCount/Index stuff.

The following example uses a vertically flipped Canvas to invert the y-axis order, so that it goes upwards. So PConverter should return positive y values.
Besides the Rectangle and Ellipse elements it draws a Line element from the previous data value to the current one by means of RelativeSource={RelativeSource PreviousData} in the value binding. It also uses a DataTrigger on the AlternationIndex to hide the first line.
<ItemsControl ... AlternationCount="2147483647">
...
<ItemsControl.ItemTemplate>
<DataTemplate>
<Canvas Width="20">
<Canvas.LayoutTransform>
<ScaleTransform ScaleY="-1"/>
</Canvas.LayoutTransform>
<Rectangle Fill="LightGray" Margin="1" Width="18"
Height="{Binding Value1, Converter={StaticResource PConverter}}"/>
<Line Stroke="DarkGreen" StrokeThickness="3"
X1="-10" X2="10"
Y1="{Binding Price,
Converter={StaticResource PConverter},
RelativeSource={RelativeSource PreviousData}}"
Y2="{Binding Price,
Converter={StaticResource PConverter}}">
<Line.Style>
<Style TargetType="Line">
<Style.Triggers>
<DataTrigger
Binding="{Binding Path=(ItemsControl.AlternationIndex),
RelativeSource={RelativeSource
AncestorType=ContentPresenter}}"
Value="0">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Line.Style>
</Line>
<Ellipse Fill="Red" Width="6" Height="6" Margin="-3" Canvas.Left="10"
Canvas.Top="{Binding Price, Converter={StaticResource PConverter}}"/>
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>
Since the value converter is now also called for a non-existing value (for PreviousData of the first item), you have to make sure that it checks if the passed value is actually a double:
public object Convert(
object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is double)) return 0d;
...
}

Related

Unable to center a canva inside a canva

I've a view in WPF where I need to center a canvas within a canvas.
I know it's not the most suitable container for this, but we have other components that will come in this canvas where it will simplify a lot our job.
So basically, I've currently this code:
<Canvas Name="RootContainer" Background="#373B3F" ClipToBounds="True" MouseLeftButtonDown="OnMainCanvasMouseLeftButtonDown">
<Canvas.DataContext>
<local:SomeViewModel/>
</Canvas.DataContext>
<Canvas Name="SomeContainer" Background="#373B3F" MouseMove="OnCanvasMouseMove" MouseWheel="OnCanvasMouseWheel">
<Canvas.Left>
<MultiBinding Converter="{StaticResource CenterValueConverter}">
<Binding ElementName="RootContainer" Path="ActualWidth" />
<Binding ElementName="SomeContainer" Path="ActualWidth" />
</MultiBinding>
</Canvas.Left>
<Canvas.Top>
<MultiBinding Converter="{StaticResource CenterValueConverter}">
<Binding ElementName="RootContainer" Path="ActualHeight" />
<Binding ElementName="SomeContainer" Path="ActualHeight" />
</MultiBinding>
</Canvas.Top>
<ItemsControl ItemsSource="{Binding SomeChilds}" Name="ItemsControl">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Left}" />
<Setter Property="Canvas.Top" Value="{Binding Top}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}" ContentTemplateSelector="{StaticResource ConventionBasedDataTemplateSelector}"
MouseLeftButtonDown="OnMouseLeftButtonDown" PreviewMouseLeftButtonUp="OnPreviewMouseLeftButtonUp" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- Some other controls over here -->
</Canvas>
</Canvas>
And this converter:
public class CenterValueConverter : IMultiValueConverter
{
public object Convert(object[] values,
Type targetType,
object parameter,
CultureInfo culture)
{
if (values == null || values.Length != 2)
{
return null;
}
double totalWidth = (double)values[0];
double size = (double)values[1];
return totalWidth / 2 - (size / 2);
}
public object[] ConvertBack(object value,
Type[] targetTypes,
object parameter,
CultureInfo culture)
{
throw new NotSupportedException();
}
}
The issue is that the second value(SomeContainer.ActualWidth/ActualHeight) always comes with a value of 0(even when I've some real elements it).
Any idea why and how to fix this? Or another XAML way of centering SomeContainer inside of the RootContainer ?
EDIT
Maybe some additional informations on why I planned to use so much Canvas.
The RootContainer one is because SomeContainer will have transformation(scale for zooming) and translation for panning
The SomeContainer could be something different I guess
The Canvas inside the ItemControls is because each elements will be positioned as a very specific place.
I guess your ActualHeight/ActualWidth are = 0 because you didn't load the window yet.
To make these calculous taking in account dimensions of Canvas you may use 'OnContentRendered' event, that will be launched after the window is displayed, so you will have their dimensions appearing. If your Canvas may change dimensions, you may also use SizeChanged event.
Even I think it is a bit complicated, and you could just use that XAML code taken from Clemen's answer :
<Canvas Background="Transparent"
SizeChanged="ViewportSizeChanged"
MouseLeftButtonDown="ViewportMouseLeftButtonDown"
MouseLeftButtonUp="ViewportMouseLeftButtonUp"
MouseMove="ViewportMouseMove"
MouseWheel="ViewportMouseWheel">
<Canvas x:Name="canvas" Width="1000" Height="600">
<Canvas.RenderTransform>
<MatrixTransform x:Name="transform"/>
</Canvas.RenderTransform>
<Ellipse Fill="Red" Width="100" Height="100" Canvas.Left="100" Canvas.Top="100"/>
<Ellipse Fill="Green" Width="100" Height="100" Canvas.Right="100" Canvas.Bottom="100"/>
</Canvas>
</Canvas>

Text separator between ListView in WPF

I'm trying to get the following from a ListView:
Text | Text | Text
I've already achieved the vertical orientation by the following
<ItemsPanelTemplate><StackPanel Orientation="Horizontal"/></ItemsPanelTemplate>
Each part(Text) is a TextBlock bound to a string in MVVM.
Preferably the lines between should just be regular vertical bars.
Any tips for achieving these vertical bars as specified??
Duplicate of How can a separator be added between items in an ItemsControl, try this:
<ItemsControl Name="theListBox">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="seperator" Text=" | "/>
<TextBlock Text="{Binding}"/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}" Value="{x:Null}">
<Setter Property="Visibility" TargetName="seperator" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
In case you have achieved to show separator in between two items, you can have a converter say LastItemInContainerToVisibilityConverter which will be binded to the visibility of separator making separator collapsed for last item and visible for all other items.
Assuming you have used Rectangle to show the seperation between items -
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}"/>
<Rectangle Visibility="{Binding RelativeSource={RelativeSource
Mode=FindAncestor, AncestorType=ListViewItem},
Converter={StaticResource
LastItemInContainerToVisibilityConverter}}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
Here goes your converter which will return if it's last item in collection -
public class LastItemInContainerToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture)
{
DependencyObject item = (DependencyObject)value;
ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(item);
return (ic.ItemContainerGenerator.IndexFromContainer(item)
== ic.Items.Count - 1) ? Visibility.Collapsed : Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter,
CultureInfo culture)
{
throw new NotImplementedException();
}
}

Run-time error: InverseBooleanConverter not found

I have a problem attempting to follow the advice in:
How to bind inverse boolean properties in WPF?
When I use with ResourceDictionary, it give run-time error. InverseBooleanConverter not found.
XMAL as follows:
<UserControl x:Class="SMTF.MasterDataView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SMTF" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DesignHeight="466" d:DesignWidth="483">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../AppResource.xaml" />
<ResourceDictionary Source="../DefaultStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<StackPanel HorizontalAlignment="Left" Margin="200,12,0,0" Name="stkMain" VerticalAlignment="Top" >
<Grid Margin="4">
<ContentControl Visibility="{Binding IsChecked, ElementName=VisibilityToggle, Converter={StaticResource InverseBooleanConverter}}" >
<Border Grid.Column="2" Style="{StaticResource MainBorderStyle}">
<HeaderedContentControl Content="{Binding Path=WorkspaceView}" ContentTemplate="{StaticResource WorkspacesTemplate}" Header="View" Style="{StaticResource MainHCCStyle}"/>
</Border>
</ContentControl>
</Grid>
<Grid DockPanel.Dock="Bottom" Margin="0,2,4,2">
<TextBlock HorizontalAlignment="Right">
<ToggleButton x:Name="VisibilityToggle" Focusable="False" Style="{StaticResource SMToggle}" Command ="{Binding ShowNew}" >
</ToggleButton>
<!--<ToggleButton x:Name="VisibilityToggle" Background="Transparent" Command ="{Binding ShowNew}" >
<Image Source="/Image/Add.png" Width="24" />
</ToggleButton>-->
</TextBlock>
</Grid>
<Grid Margin="4">
<ContentControl Visibility="{Binding IsChecked, ElementName=VisibilityToggle, Converter={StaticResource BoolToVisibility}}" >
<Border Grid.Column="2" Style="{StaticResource MainBorderStyle}">
<HeaderedContentControl Content="{Binding Path=WorkspaceEdit}" ContentTemplate="{StaticResource WorkspacesTemplate}" Header="Configure" Style="{StaticResource MainHCCStyle}"/>
</Border>
</ContentControl>
</Grid>
</StackPanel>
</Grid>
</UserControl>
I'm using the same code provided in the link.
ie:
[ValueConversion(typeof(bool), typeof(bool))]
public class InverseBooleanConverter: IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (targetType != typeof(bool))
throw new InvalidOperationException("The target must be a boolean");
return !(bool)value;
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
#endregion
}
in the AppResource XML
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:SMTF">
<vm:InverseBooleanConverter x:Key="InverseBoolToVisibility" />
.....
.....
</ResourceDictionary>
Thanks in advance
NS
An alternative to converters for style related binding is to use Style.Triggers, the following shows a canvas when checkbox IsChecked = false, which would otherwise require an InverseBooleanConverter.
<Canvas x:Name="Overlay">
<Canvas.Style>
<Style TargetType="Canvas">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=MyCheckbox}" Value="True">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Binding="{Binding IsChecked, ElementName=MyCheckbox}" Value="False">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Canvas.Style>
<Rectangle Canvas.ZIndex="3" Fill="#99333333" Height="25" Stroke="Transparent" Width="293" Canvas.Left="10" Canvas.Top="-25"/>
</Canvas>
The key you are using is not correct. You resource key is InverseBoolToVisibility, while you have used InverseBooleanConverter as key.
Change the resource key to refer to correct resource as
<ContentControl Visibility="{Binding IsChecked, ElementName=VisibilityToggle, Converter={StaticResource InverseBoolToVisibility}}" >
Also your implementation for convereter is wrong. If you want to change the Visibility based on Boolean inverse value update your converter code as:
public class InverseBooleanConverter: IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (targetType != typeof(Visibility))
throw new InvalidOperationException("The target must be a boolean");
if(!(bool)value)
{
return Visibility.Visible;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
#endregion
}

WPF Tooltip with controls

I have a project in which i would like to be able to have a tooltip on some control that would incoporate some controls like textbox and datepicker. The idea would be to have some sort of a popup window with limited graphic but some control wo interact.
I know how to add a 'normal' tooltip to a control, but when you move, the tooltip disapear so I can't interact with it.
is this possible? If so how and if not, is there any alternative to this ?
Thanks
You should use a Popup instead of a ToolTip
Example. A Popup is opened when the mouse moves over the TextBox and stays open as long as the mouse is over the TextBox or the Popup
<TextBox Name="textBox"
Text="Popup On Mouse Over"
HorizontalAlignment="Left"/>
<Popup PlacementTarget="{Binding ElementName=textBox}"
Placement="Bottom">
<Popup.IsOpen>
<MultiBinding Mode="OneWay" Converter="{StaticResource BooleanOrConverter}">
<Binding Mode="OneWay" ElementName="textBox" Path="IsMouseOver"/>
<Binding RelativeSource="{RelativeSource Self}" Path="IsMouseOver" />
</MultiBinding>
</Popup.IsOpen>
<StackPanel>
<TextBox Text="Some Text.."/>
<DatePicker/>
</StackPanel>
</Popup>
Is uses a BooleanOrConverter
public class BooleanOrConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
foreach (object booleanValue in values)
{
if (booleanValue is bool == false)
{
throw new ApplicationException("BooleanOrConverter only accepts boolean as datatype");
}
if ((bool)booleanValue == true)
{
return true;
}
}
return false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}
Update
To do this for a cell in DataGrid you have a few options. Two of them are to add a Popup inside the DataTemplates for DataGridTemplateColumn, or you can add it to the DataGridCell Template. Here is an example of the later. It will require you to set SelectionMode="Single" and SelectionUnit="Cell" on the DataGrid
<DataGrid SelectionMode="Single"
SelectionUnit="Cell"
...>
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<Popup PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}"
Placement="Right"
IsOpen="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}">
<StackPanel>
<TextBox Text="Some Text.."/>
<DatePicker/>
</StackPanel>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.CellStyle>
<!--...-->
</DataGrid>

Rescale listboxes or other items? but not text (WPF)

The question is quite clear. I have listviews or listboxes in my view.
If i make my screen smaller, i want that my text (labels etc) stay the same size. But the listviews and listboxes have to become smaller, eventually with a scrollbar?
how do i do this?
Thanks
the ListBox has a ScrollViewer built in.
<ListBox ScrollViewer.VerticalScrollBarVisibility="Auto" />
The question is quite clear.
Well, not exactly. But I think this is what you're looking for. First, create a value converter that takes a Double and returns its reciprocal:
public class ReciprocalValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Double? d = value as Double?;
return (d == null || d == 0)
? null
: 1/d;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Now you can scale any content control, using a ScaleTransform, and use the ReciprocalValueConverter to keep any individual element contained within it to the original scale. So if the content control's scale is doubled, the content that you want to remain unchanged has its scale halved.
This example shows both scaling content controls and "unscaling" the items in a list box by assigning the LayoutTransform to each item:
<Window x:Class="ScaleTransformDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ScaleTransformDemo="clr-namespace:ScaleTransformDemo" Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ScaleTransformDemo:ReciprocalValueConverter x:Key="Reciprocal" />
</Window.Resources>
<DockPanel>
<Slider x:Name="ScaleSlider"
Orientation="Vertical"
Minimum=".2"
Maximum="4"
Value="1" />
<DockPanel>
<DockPanel.LayoutTransform>
<ScaleTransform ScaleX="{Binding ElementName=ScaleSlider, Path=Value}"
ScaleY="{Binding ElementName=ScaleSlider, Path=Value}" />
</DockPanel.LayoutTransform>
<Label DockPanel.Dock="Top">
The content of this label scales with the slider.
</Label>
<Label DockPanel.Dock="Top">
<Label.LayoutTransform>
<ScaleTransform ScaleX="{Binding ElementName=ScaleSlider, Path=Value, Converter={StaticResource Reciprocal}}"
ScaleY="{Binding ElementName=ScaleSlider, Path=Value, Converter={StaticResource Reciprocal}}" />
</Label.LayoutTransform>
<Label.Content>
This label's content stays the same size.
</Label.Content>
</Label>
<Label DockPanel.Dock="Top">
The ListBox below scales with the slider, too, but the ListBoxItems don't:
</Label>
<ListBox Height="50"
DockPanel.Dock="Top">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform ScaleX="{Binding ElementName=ScaleSlider, Path=Value, Converter={StaticResource Reciprocal}}"
ScaleY="{Binding ElementName=ScaleSlider, Path=Value, Converter={StaticResource Reciprocal}}" />
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBoxItem>Item 1</ListBoxItem>
<ListBoxItem>Item 2</ListBoxItem>
<ListBoxItem>Item 3</ListBoxItem>
<ListBoxItem>Item 4</ListBoxItem>
<ListBoxItem>Item 5</ListBoxItem>
<ListBoxItem>Item 6</ListBoxItem>
</ListBox>
<TextBlock DockPanel.Dock="Top" />
</DockPanel>
</DockPanel>
</Window>

Resources