Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.

Join them; it only takes a minute:

Sign up
Join the Stack Overflow community to:
  1. Ask programming questions
  2. Answer and help your peers
  3. Get recognized for your expertise

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());
        }
share|improve this question
up vote 3 down vote accepted

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>
share|improve this answer
    
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! – Eric Oct 19 '11 at 22:25
1  
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. – Josh Oct 20 '11 at 12:57

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

share|improve this answer
    
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 – Eric Oct 19 '11 at 18:11
    
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. – Eric Oct 19 '11 at 18:57

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.