WPF Image Zooming - wpf

I have a Viewbox with an Image inside of it. This is great since the Viewbox will scale the Image to fit the window. However, I need to be able to zoom the image to its full size and show scroll bars and I am having a hard time figuring out how to do this.
Here's what I have right now. Can anyone give some pointers on how I can modify this to implement the above functionality?
<Viewbox x:Name="viewbox">
<StackPanel>
<Image x:Name="image" Source="ranch.jpg" />
</StackPanel>
</Viewbox>
Edit:
Just to clarify. I need both ways of viewing the image, the viewbox style of fitting the window AND the ability to toggle to an Actual Size view that shows scrollbars and doesn't resize the image.

You don't need a Viewbox here, by putting the Image in a ScrollViewer and manipulating the VerticalScrollBarVisibility and HorizontalScrollBarVisibility properties, you can make the Image scale or not:
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<CheckBox x:Name="chkActualSize" Grid.Row="0" Content="Actual Size"/>
<ScrollViewer Grid.Row="1">
<ScrollViewer.Style>
<Style TargetType="{x:Type ScrollViewer}">
<Setter Property="HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="VerticalScrollBarVisibility" Value="Disabled"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=chkActualSize}" Value="True">
<Setter Property="HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ScrollViewer.Style>
<Image Source="http://sipi.usc.edu/database/misc/4.1.01.tiff" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</ScrollViewer>
</Grid>

<ScrollViewer HorizontalScrollBarVisibility="Auto">
<Viewbox>
<Image Source="ranch.jpg"/>
</Viewbox>
</ScrollViewer>

Based on your edit that you need to toggle the two approaches, I would do this in one of two ways.
Have two elements with the image. The Image element inside a ScrollViewer without the Viewbox will give you the full size image, and the Viewbox version will scale it. Then you can toggle the two depending on what you want to show.
Use a binding expression on the Height and Width properties of the Image and enclose it inside the scrollviewer. When you want to scale it (in some sort of trigger), set the Height to a binding expression that accesses the ActualHeight property of the ScrollViewer or whatever container is just above that (using RelativeSource to access the nearest ancestor something like the following):
{Binding Path=ActualHeight,
RelativeSource={RelativeSource AncestorType={x:Type ScrollViewer}}}

Thought I would post my solution for anyone looking.
<Slider Width="200" Value="500" Interval="25" Maximum="1000" x:Name="TestImageSlider" Minimum="-50" />
<ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Auto">
<Image Source="{Binding SelectedScannedImage.ScannedImage}" Width="{Binding Path=Value, ElementName=TestImageSlider}" />
</ScrollViewer>

Related

Weird behaviour when moving VisualBrush into a Style

I've been working on a solution to have a dashed Border control. After some browsing I came across this which works; https://stackoverflow.com/a/47300149/9703942
However, Ideally I want my borders to be controlled by styles so anyone can use them across our many projects. So I did the following:
<Style x:Key="Border-Dashed" TargetType="{x:Type Border}" BasedOn="{StaticResource Border-Base}">
<Setter Property="BorderThickness" Value="{StaticResource Border-Thickness-Solid}" />
<Setter Property="BorderBrush">
<Setter.Value>
<VisualBrush>
<VisualBrush.Visual>
<Rectangle Stroke="HotPink"
StrokeDashArray="4,4"
Width="{Binding Path=ActualWidth, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType={x:Type Border}}}"
Height="{Binding Path=ActualHeight, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType={x:Type Border}}}"/>
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
</Style>
This just doesn't work. I believe the Rectangle is drawn before the width and height of the border are correctly set. However, once they are set it's not updating the binding correctly?
So my question is, what am I doing wrong and can I achieve what I want to in styles alone?
Any help would be greatly appreciated!
The problem here is that RelativeSource bindings only work on objects in the same visual or logical tree, and a brush assignment is not a child "control" as such.
In any case, using a VisualBrush when you really want a stroke seems to me a bit like trying to fit a square peg into a round hole. Personally I think Border should have supported templating so that the brush could have been replaced with a pen. That wasn't done, so if you want to do this properly then I think you're left with the choice of either re-writing the Border control to support this, or replacing it with ContentControl instead:
<Window.Resources>
<ControlTemplate x:Key="BorderControl" TargetType="ContentControl">
<Grid>
<Rectangle Stroke="HotPink" StrokeDashArray="4,4" />
<ContentPresenter Margin="1"/>
</Grid>
</ControlTemplate>
</Window.Resources>
<Grid Width="200" Height="100">
<ContentControl Template="{StaticResource BorderControl}">
<TextBlock Text="Whatever" />
</ContentControl>
</Grid>

Height of WPF TreeViewItem controltemplate not collapsing

I have an issue that I have been trying to solve for a week and have not only played around extensively trying to figure this out but have done lots of research on StackOverFlow and other websites on how to fix this problem. Just to be clear, I have been learning WPF for about 3 or so months and come from WinForms and am still in the learning phase.
Here is my problem.
I have a TreeViewItems that I am adding to a TreeView control. These TreeView items use a Style that creates a custom look that I am trying to accomplish that is pretty much the look and feel of the entire application. The Style uses an explicit Setter.Value against the Template property to create the custom look of the TreeView item. It has its own custom expander arrow, TextBlock header that is bound to the TreeViewItem header, and also of course a ContentPresenter and a ItemsPresenter. There is also a trigger that is wired up to the value of the TreeViewItem's IsExpanded value so that way the ItemsPresenter can be shown or hidden when the TreeViewItem is expanded or collapsed. Everything works as it should except the collapse and expand part. Of course the ItemsPresenter hides and shows like it should but the TreeViewItem itself does not actually collapse its height when the IsExpanded is false. To show what I mean, here are 2 pictures to illustrate what is going on. I added a green border around the grid in the template of the style to show that the individual TreeViewItem itself is not shrinking its "height" when collapsed.
Expanded
Pic of expanded tree view item
Collapsed
Pic of collapsed tree view item
As you can see, the green border, or the treeview item itself is still the same height when collapsed as it is when expanded. Here is the XAML used to create the custom style of the TreeViewItem's themselves.
TreeViewItem Style XAML Code:
<Style x:Key="TreeViewItemStyle" TargetType="TreeViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeViewItem">
<Border x:Name="MyBorder" BorderThickness="1" BorderBrush="LawnGreen">
<Grid HorizontalAlignment="Left" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="25"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ui:TreeViewItemExpander x:Name="TreeViewItemExpander" Grid.Row="0" Grid.Column="0" IsPointingDown="{TemplateBinding IsExpanded}"/>
<!--This represents the text for the tree view item itself-->
<TextBlock Text="{TemplateBinding Header}" Grid.Row ="0" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Center" Foreground="White"/>
<ContentPresenter x:Name="ContentPresenter" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<ItemsPresenter x:Name="ItemsPresenter" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" Visibility="Hidden"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="ItemsPresenter" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This code below is how I am using the style
<TreeView Style="{StaticResource TreeViewStyle}" Width="200" Margin="419,337,19,328">
<controls:CustomTreeViewItem Header="Folder 1" Style="{StaticResource TreeViewItemStyle}">
<Button Content="Item 1" HorizontalAlignment="Left" VerticalAlignment="Top" Height="20"/>
<Button Content="Item 2" HorizontalAlignment="Left" VerticalAlignment="Top" Height="20"/>
</controls:CustomTreeViewItem>
</TreeView>
Thanks for any input or help that anybody can provide. I hope that I was clear enough.
I figured it out. What I did was just add a setter in the IsExpanded trigger to set the property of the grid row that the ItemsPresenter resides in. All I did was set the height of the row to 0 which essentially hides the items. Here is the code of the trigger itself from the code above with the change applied.
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="Items" Property="Visibility" Value="Visible"/>
<Setter TargetName="ItemsRow" Property="Height" Value="0"/>
</Trigger>
</ControlTemplate.Triggers>
I am interested though if anybody else has a better solution. After I figured this out, I then thought about animating the height of the row until it is 0 to give a better effect, but was not successful. I found out that StoryBoards are freezable and are frozen when inside of a Style or ControlTemplate. That means if you wanted it to be animated, then the animation of the item collapsing would have to be implemented with code behind, or on each TreeViewItem individually? I am sure there is a better way. If I find out how to accomplish this, I will update this post for everybody to reference. Please feel free to add to this post on a better solution!!

WPF - Button on Image Moves at Run Time

I have a program that displays a grid that contains an image and 3 buttons. The buttons have been sized in the Visual Studio designer to fit inside separate circles (each approx 1/4" in diameter). When I run the program each of the buttons all move down and to the right about 1/2 the width of the button. If I add an explicit width and height to each button I can keep the size the same but the buttons still moves slightly to the right and maybe even down slightly.
My guess is that it has to do with how Windows has displayed the image to fit on the screen and that this scaling/positioning has not been applied to the buttons. If so, I have no idea how to correct the issue.
Any ideas on how to correct this problem would be greatly appreciated.
Chris
My XAML code:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Height}"
Width="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Width}"
WindowStartupLocation="CenterScreen"
Background="CornflowerBlue"
ResizeMode="CanMinimize"
>
<Window.Resources>
<Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Black"/>
<Setter Property="Opacity" Value="1"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid Name="grid1">
<Image Name="image" Source="D:\CEP\Image1.jpg" Stretch="Uniform">
</Image>
<Button Margin="494,0,1155,801" Click="button_407_Click"></Button>
<Button Margin="339,107,1310,856" />
<Button Margin="401,102,1248,860" />
</Grid>
Set the Stretch property of the Image to None to prevent the image from sizing.
You have positioned the buttons by setting their margins. As soon as the window is resized their positions and sizes will change.
Add a Canvas to the grid and put the image and the buttons on the canvas using absolute positioning (Canvas.Left="..." Canvas.Top="..."
If, after doing this, you do not like the results because you still want to resize the the images and move the buttons in sync you could wrap the Canvas in a ViewBox to make it scale.
EDIT
<Grid>
<Viewbox>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Image Source="Images\wp_1680.jpg" Width="300" Height="200"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Canvas Width="300" Height="200"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Canvas.Top="25" Canvas.Left="50" Content="OK"/>
<Button Canvas.Top="125" Canvas.Left="150" Content="Cancel"/>
</Canvas>
</Grid>
</Viewbox>
</Grid>
This solution includes nice scaling through the Viewbox, but it can be removed as well.
Please organize all your posts. If you want to say something about my answer add it as a comment to my answer if you want add to your question, edit the question.

Use checkbox as togglebutton in expander

Im quite new to wpf and have to following problem.
I need to create a List (i am using a listbox) of items that can be expanded (expander).
The problem is, that they can be expanded, only if they have been 'selected'.
Each listboxitem should have a checkbox and some text.
So very basic example to illustrate what i mean:
<listbox>
<item>(checkbox) John Doe</item>
<item>(checkbox) Mike Murray</item>
</listbox>
If any (so multiple is allowed) of the checkboxes in the listbox are checked, then
the item expands showing more data.
Again an example:
<listbox>
<item>
(checkbox-checked) John Doe
Some extra data shown in expanded area
</item>
<item>
(checkbox-unchecked) Mike Murray</item>
</listbox>
I cant get a expander to use a checkbox as 'togglebutton'.
Could anyone help me out? Some example code would be very welcome...
This should do the trick:
<ListBox>
<ListBox.Resources>
<Style TargetType="Expander">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Expander">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<CheckBox
IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
Content="{TemplateBinding Header}"
/>
<ContentControl
x:Name="body"
Grid.Row="1" Content="{TemplateBinding Content}"
/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="False">
<Setter TargetName="body" Property="Visibility" Value="Collapsed" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>
<Expander Header="One">
Content one
</Expander>
<Expander Header="Two">
Content two
</Expander>
</ListBox>
I've defined a Style here that changes the Template of any Expander controls to which the Style is applied. (And since I've put the Style in the ListBox.Resources it'll automatically apply to an Expander controls in the list.)
The trick to getting the CheckBox to work is that when you put it (or indeed any ToggleButton based control) into an Expander template, you need to use a data binding configured with its RelativeSource set to the TemplatedParent. This enables two-way binding - it means that not only does the CheckBox reflect the current state of the expander, it is also able to change the current state.
All you need to add a check box in the header is this code:
<telerik:RadExpander.Header>
<StackPanel Orientation="Horizontal">
<CheckBox VerticalAlignment="Center"/>
<TextBlock Margin="5,0,0,0">Legend</TextBlock>
</StackPanel>
</telerik:RadExpander.Header>
I am using Rad Control, The same can be done using the standard expander

WPF ListBox virtualization screws up displayed items

Problem
We need to efficiently display a large (>1000) number of objects in a WPF ListBox control.
We are relying on the WPF ListBox’s virtualization (via VirtualizingStackPanel) to efficiently display these items.
Bug: The WPF ListBox control does not display items correctly when using virtualization.
How to Reproduce
We have distilled the problem to the standalone xaml shown below.
Copy and paste the xaml into XAMLPad.
Initially, there is no selected item in the ListBox, so as expected, all items are the same size and they completely fill the available space.
Now, click on the first item.
As expected, because of our DataTemplate, the selected item will expand to show additional information.
As expected, this causes the horizontal scrollbar to appear, since the selected item is now wider than the available space.
Now use the mouse to click and drag the horizontal scrollbar to the right.
Bug: the non-selected visible items no longer stretch to fill the available space. All the visible items should be the same width.
Is this a known bug?
Is there any way to fix this, either via XAML or programmatically?
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<Page.Resources>
<DataTemplate x:Key="MyGroupItemTemplate">
<Border Background="White"
TextElement.Foreground="Black"
BorderThickness="1"
BorderBrush="Black"
CornerRadius="10,10,10,10"
Cursor="Hand"
Padding="5,5,5,5"
Margin="2"
>
<StackPanel>
<TextBlock Text="{Binding Path=Text, FallbackValue=[Content]}" />
<TextBlock x:Name="_details" Visibility="Collapsed" Margin="0,10,0,10" Text="[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]" />
</StackPanel>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsSelected}"
Value="True">
<Setter Property="TextElement.FontWeight"
TargetName="_details"
Value="Bold"/>
<Setter Property="Visibility"
TargetName="_details"
Value="Visible"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Page.Resources>
<DockPanel x:Name="LayoutRoot">
<Slider x:Name="_slider"
DockPanel.Dock="Bottom"
Value="{Binding FontSize, ElementName=_list, Mode=TwoWay}"
Maximum="100"
ToolTip="Font Size"
AutoToolTipPlacement="BottomRight"/>
<!--
I want the items in this ListBox to completly fill the available space.
Therefore, I set HorizontalContentAlignment="Stretch".
By default, the WPF ListBox control uses a VirtualizingStackPanel.
This makes it possible to view large numbers of items efficiently.
You can turn on/off this feature by setting the ScrollViewer.CanContentScroll to "True"/"False".
Bug: when virtualization is enabled (ScrollViewer.CanContentScroll="True"), the unselected
ListBox items will no longer stretch to fill the available horizontal space.
The only workaround is to disable virtualization (ScrollViewer.CanContentScroll="False").
-->
<ListBox x:Name="_list"
ScrollViewer.CanContentScroll="True"
Background="Gray"
Foreground="White"
IsSynchronizedWithCurrentItem="True"
TextElement.FontSize="28"
HorizontalContentAlignment="Stretch"
ItemTemplate="{DynamicResource MyGroupItemTemplate}">
<TextBlock Text="[1] This is item 1." />
<TextBlock Text="[2] This is item 2." />
<TextBlock Text="[3] This is item 3." />
<TextBlock Text="[4] This is item 4." />
<TextBlock Text="[5] This is item 5." />
<TextBlock Text="[6] This is item 6." />
<TextBlock Text="[7] This is item 7." />
<TextBlock Text="[8] This is item 8." />
<TextBlock Text="[9] This is item 9." />
<TextBlock Text="[10] This is item 10." />
</ListBox>
</DockPanel>
</Page>
I spent more time attempting this than I probably should have, and couldn't get it to work. I understand what's going on here, but in pure XAML, I'm having trouble figuring out how to solve the issue. I think I see how to solve the problem, but it involves a converter.
Warning: Things are going to get complicated as I explain my conclusions.
The underlying problem comes from the fact that the Width of the controls stretch to the Width of their container. When virtualization is enabled, the Width will not change. In the underlying ScrollViewer inside of ListBox, the ViewportWidth property corresponds to the Width you see. When another control stretches out further (you select it), the ViewportWidth is still the same, but the ExtentWidth shows the full width. Binding the width of all controls to that of the ExtentWidth should work...
But it doesn't. I set the FontSize to 100 for quicker testing in my case. When an item is selected, ExtentWidth="4109.13. Going down the tree to your ControlTemplate's Border, I see ActualWidth="4107.13". Why the 2 pixel difference? ListBoxItem contains a Border with 2 Pixel padding, causing the ContentPresenter to render slightly smaller.
I added the following Style with help from here to allow me to directly access the ExtentWidth:
<Style x:Key="{x:Type ListBox}" TargetType="ListBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Border
Name="Border"
Background="White"
BorderBrush="Black"
BorderThickness="1"
CornerRadius="2">
<ScrollViewer
Name="scrollViewer"
Margin="0"
Focusable="false">
<StackPanel IsItemsHost="True" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background"
Value="White" />
<Setter TargetName="Border" Property="BorderBrush"
Value="Black" />
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Note I added a name to ScrollViewer for this purpose.
Then, I attempted to bind the Width of your Border to the ExtentWidth:
Width="{Binding ElementName=scrollViewer, Path=ExtentWidth}"
However, because of that 2 pixel padding, the controls will resize in an infinite loop, with the padding adding 2 pixels to the ExtentWidth, which resizes the Border width, which adds 2 more pixels to the ExtentWidth, etc. until you delete the code and refresh.
If you added a Converter that subtracted 2 from the ExtentWidth, I think this might work. However, when the scroll bar does not exist (you have not selected anything), ExtentWidth="0". Thus, binding to MinWidth instead of Width may work better so the items appear correctly when no scroll bar is visible:
MinWidth="{Binding ElementName=scrollViewer, Path=ExtentWidth, Converter={StaticResource PaddingSubtractor}}"
A better solution would be if you could directly databind the MinWidth of the ListBoxItem itself. You could bind directly to ExtentWidth, and no converter would be necessary. However I have no idea how to get access to that item.
Edit: For organization sake, here's the clip required to do that. Makes everything else unnecessary:
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="MinWidth" Value="{Binding Path=ExtentWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollViewer}}}" />
</Style>
Thanks to Will's great analysis!
Based on Will's suggestion: "A better solution would be if you could directly databind the MinWidth of the ListBoxItem itself...However I have no idea how to get access to that item", I was able to implement that using pure xaml, as follows:
<ListBox x:Name="_list"
Background="Gray"
Foreground="White"
IsSynchronizedWithCurrentItem="True"
TextElement.FontSize="28"
HorizontalContentAlignment="Stretch"
ItemTemplate="{DynamicResource MyGroupItemTemplate}">
<!-- Here is Will's suggestion, implemented in pure xaml. Seems to work.
Next problem is if you drag the Slider to the right to increase the FontSize.
This will make the horizontal scroll bar appear, as expected.
Problem: the horizontal scroll bar never goes away if you drag the Slider to the left to reduce the FontSize.
-->
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="MinWidth" Value="{Binding Path=ExtentWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollViewer}}}" />
</Style>
</ListBox.Resources>
<TextBlock Text="[1] This is item 1." />
<TextBlock Text="[2] This is item 2." />
<TextBlock Text="[3] This is item 3." />
<TextBlock Text="[4] This is item 4." />
<TextBlock Text="[5] This is item 5." />
<TextBlock Text="[6] This is item 6." />
<TextBlock Text="[7] This is item 7." />
<TextBlock Text="[8] This is item 8." />
<TextBlock Text="[9] This is item 9." />
<TextBlock Text="[10] This is item 10." />
</ListBox>
I got the idea from Adam Nathan's great book, "Windows Presentation Foundation Unleashed".
So, this seems to fix the original problem.
New Problem
You notice that there is a Slider control in the xaml that let's you increase/decrease the ListBox font. The idea here was to allow the user the ability to scale the ListBox content up or down for easier visibility.
If you first drag the Slider to the right to increase the FontSize, this will make the horizontal scroll bar appear, as expected. The new problem is that the horizontal scroll bar never goes away if you drag the Slider to the left to reduce the FontSize.
Any ideas?

Resources