4

I've looked all over and have been unable to find a solution to my problem. My entire approach might be off and I could start over if I'm simply tackling this the wrong way.

I have a WPF window with a header, a listbox, an a footer. I want to programatically add n number of user controls to the listbox and have the listbox itself be scrollable (not the entire window). I also want to turn off what happens when you click an item in the listbox (the background highlights blue - I want it to change the background of the user control now treat it as a big listbox item) Really a listbox might even be the wrong thing.

I've tried stackpanels, scrollpanels, and a half dozen other approaches. Listbox just happens to be what I'm using now. I have a dozen different types of usercontrols and based on business logic some combination of them needs to be displayed, so really I need a scrollable usercontrol container where I can determine which one, if any, has been clicked.

Here is the XAML for MainWindow.xaml

<Window x:Class="LayoutTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:customUserControls="clr-namespace:LayoutTest.Properties"
        Title="Layout Sample" Height="Auto" MaxWidth="600" MinWidth="600" Width="600"  ResizeMode="CanMinimize" WindowStartupLocation="CenterScreen">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="393*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>        
        <TextBlock Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="24" TextAlignment="Center" Margin="5,5,210,5">Header</TextBlock>
        <ListBox x:Name="lstPanels" Grid.Row="1" Grid.ColumnSpan="2" HorizontalContentAlignment="Stretch" Margin="0,0,0,17"/>        
        <TextBlock Grid.Column="1" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="24" TextAlignment="Center" Margin="5,5,210,5">Footer</TextBlock>
    </Grid>
</Window>

And here is the XAML for UserControl1.xaml

<UserControl x:Class="LayoutTest.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="100" d:DesignWidth="500" Padding="0" Margin="10">
    <Border BorderThickness="2" BorderBrush="OrangeRed" CornerRadius="10">
        <StackPanel Orientation="Horizontal">
            <Image x:Name="imgLogo" MinWidth="100" MinHeight="100" MaxWidth="100" MaxHeight="100" />
            <Grid MinWidth="400">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="108*" />
                    <ColumnDefinition Width="104*" />
                    <ColumnDefinition Width="188*" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="25*" />
                    <RowDefinition Height="35*" />
                </Grid.RowDefinitions>
                <TextBlock Text="xxxxx:" Margin="5,2,2,2" />
                <TextBlock Grid.Column="1" Grid.ColumnSpan="2"  Text="xxxxx" Margin="2" />
                <TextBlock Text="xxxxx:" Grid.Row="1" Margin="5,2,2,2" />
                <TextBlock Grid.Column="1" Grid.Row="1" Text="xxxxxx" Grid.ColumnSpan="2" Margin="2" />
                <CheckBox Content="xxxxxx" Grid.Row="3" Name="chkSkipConfiguration" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,0,112,5" Width="200" HorizontalAlignment="Right" />
                <Button Content="xxxxx" Grid.Column="2" Grid.Row="3"  Padding="0" HorizontalAlignment="Right" Width="50" Margin="0,0,19,0"  />
            </Grid>
        </StackPanel>
    </Border>
</UserControl>

And lastly in the constructor for MainWindow.xaml.cs there is the following snippet to create 10 instances of the user control:

        for(int i=0; i<10; i++)
        {
            lstPanels.Items.Add(new UserControl1());
        }

2 Answers 2

3

First give your ListBox a height and width, either explicitly or by Stretching it within a container. With your ListBox you can define a vertical scrollbar using ScrollViewer.VerticalScrollBarVisibility="Visible". If you have a height defined then it should automatically enable scrolling as your added items extend past that height.

As far as the highlighting goes, try this setter. Just place it in a style targeted for the ListBoxItem type:

  <Setter Property="Template">
     <Setter.Value>
        <ControlTemplate TargetType="{x:Type ListBoxItem}">
           <Border x:Name="border" Background="Transparent">
              <ContentPresenter />
           </Border>
           <ControlTemplate.Triggers>
              <Trigger Property="IsSelected" Value="true">
                 <Setter TargetName="border" Property="Background">
                    <Setter.Value>Transparent</Setter.Value>
                 </Setter>
              </Trigger>
           </ControlTemplate.Triggers>
        </ControlTemplate>
     </Setter.Value>
  </Setter>
Sign up to request clarification or add additional context in comments.

2 Comments

I was able to get the listbox to scroll, so thank you for that, but I'm stuck with this style. Using this markup selecting a listitem removes the default blue background, so that is definitely an improvement. What would I need to change for it to set the background color of the UserControl (which is what the listboxitem contains) instead? The UserControl, as shown in my original example, has a orange border. It would be nice if when that item is clicked I was able to shade the space within the border of the usercontrol. Thanks!
If you leave that style on the ListBoxItem, I believe you can achieve what you want by adding a property to your control called IsSelected. If you handle the PreviewMouseDown or PreviewMouseUp of the Border element, and set IsSelected to !IsSelected each event, you can then add a DataTrigger for the IsSelected property to change the background of the Border or the Grid.
1

Just off the cuff... Is there a reason you can't wrap things with a ScrollViewer and have the contained controls respond to the clicks by passing messages? ScrollViewer: http://msdn.microsoft.com/en-us/library/ms750665.aspx

2 Comments

I tried scrollviewers at one point but that scrolled the entire page. I couldn't find any way to get a bunch of usercontrol's in the middle of a page to scroll while keeping the header and footer visible at all times. The example in the document has scrollviewer as the top level element. It might be possible but I couldn't get the syntax right when I tried it
I just tried replacing the listbox with a scrollviewer and placed a stackpanel inside the scrollviewer. I then added my usercontrols to the stackpanel.children instead of listbox.items and got the same result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.