views:

141

answers:

5

I have the following construct, which shows a DataBound ListBox and a Button inside a StackPanel, which again is placed inside a ScrollViewer:

    <ScrollViewer VerticalScrollBarVisibility="Visible"
                  Height="400">
        <StackPanel Orientation="Vertical"
                    MaxHeight="400">
            <ListBox x:Name="LbTelEntries"
                     SelectionChanged="LbTelEntries_SelectionChanged"
                     MaxHeight="340"
                     VerticalAlignment="Top"
                     ItemsSource="{Binding Path=TelItems}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Templates:ListBoxItemTemplateSelector Content="{Binding}" />
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
            <Button x:Name="BtMoreTelEntries"
                    Content="More Results"
                    Click="BtMoreTelEntries_Click"
                    Visibility="{Binding Path=NumberRemainingResults, Converter={StaticResource NullToVisConverter}}"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Bottom"
                    Height="70"
                    Width="410"
                    Margin="0 0 0 0"
                    ></Button>
        </StackPanel>
    </ScrollViewer>

My problem is, that the Button should only appear, when the ListBox is scrolled to the end. Once the Button is clicked, the content of the ListBox is exchanged and the Button should again move to the end of the ListBox...

How would I accomplish this?

EDIT: I should mention, that I am also implementing an ItemTemplate. See below:

<DataTemplate x:Key="ListBoxItemVmTemplate">
    <Grid DataContext="{Binding}">
        <StackPanel Orientation="Horizontal">
            <Border x:Name="UpperListBoxTemplateBorder"
                    Height="42"
                    Width="44"
                    BorderBrush="White"
                    BorderThickness="2.5"
                    CornerRadius="100"
                    Margin="10,16,0,0"
                    VerticalAlignment="Top">
                <Path x:Name="DataTemplatePath"
                      Height="16"
                      Width="11"
                      Fill="White"
                      Stretch="Fill"
                      Margin="4,0,0,0"
                      HorizontalAlignment="Center"
                      VerticalAlignment="Center"
                      UseLayoutRounding="False"
                      Data="M337.59924,129.61948 L337.59924,141.51501 L345.5704,135.87381 z" />
            </Border>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="40"></RowDefinition>
                    <RowDefinition Height="22"></RowDefinition>
                </Grid.RowDefinitions>
                <StackPanel Orientation="Horizontal"
                            Grid.Row="0">
                    <Controls:EllipsisTextBlock Text="{Binding DataModel.Title}"
                                                MaxWidth="410"
                                                Margin="18 12 0 0" />
                </StackPanel>
                <StackPanel Orientation="Horizontal"
                            Grid.Row="1">
                    <Controls:EllipsisTextBlock Text="{Binding DataModel.Street}"
                                                FontSize="16"
                                                MaxWidth="410"
                                                Margin="18 -3 0 0" />
                    <Controls:EllipsisTextBlock Text="{Binding DataModel.ZipCode}"
                                                FontSize="16"
                                                MaxWidth="410"
                                                Margin="18 -3 0 0" />
                    <Controls:EllipsisTextBlock Text="{Binding DataModel.City}"
                                                FontSize="16"
                                                MaxWidth="410"
                                                Margin="18 -3 0 0" />
                </StackPanel>
            </Grid>
        </StackPanel>
    </Grid>
</DataTemplate>
A: 

I do not fully understand your question but what I can see that is wrong is that you put a stackpanel in a scrollviewer but you are using to much fixed (max)heights so the scrollviewer has no sense anymore.

Try by removing the height property from the Stackpanel and the listbox to see if it does what you would like.

Wouter Janssens - Xelos bvba
If I remove the MaxHeight on the ListBox, then the StackPanel keeps growing to fit the size and I loose all scrolling functionality. I read here on Stackoverflow, that MaxHeight should be set.What I want is to see the ListBox content (which is longer than the phone display) but have the button hidden, until the ListBox is scrolled to the end.
froeschli
A: 

It seems it's not possible to achieve what I had in mind. Current solution is this:

<ScrollViewer VerticalScrollBarVisibility="Visible">
    <StackPanel Orientation="Vertical">
        <ListBox x:Name="LbTelEntries"
                 SelectionChanged="LbTelEntries_SelectionChanged"
                 MaxHeight="340"
                 VerticalAlignment="Top"
                 ItemsSource="{Binding Path=TelItems}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Templates:ListBoxItemTemplateSelector Content="{Binding}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button x:Name="BtMoreTelEntries"
                Content="More Results"
                Click="BtMoreTelEntries_Click"
                Visibility="{Binding Path=NumberRemainingResults, Converter={StaticResource NullToVisConverter}}"
                HorizontalAlignment="Center"
                VerticalAlignment="Bottom"
                Height="70"
                Width="410"
                Margin="0 0 0 0"
                ></Button>
    </StackPanel>
</ScrollViewer>

With this, I permanently see the Button below the ListBox. Once the Button is clicked, the content of the ListBox is extended. As far as I can tell, there is no way of checking, if the ListBox has scrolled to the end or not...

froeschli
A: 

You should remove the ScrollViewer that is implicitly used in the ListBox's template, as follows:

<ListBox ...>
    <ListBox.Template>
        <ControlTemplate>
            <ItemsPresenter/>
        </ControlTemplate>
    </ListBox.Template>
    ...
</ListBox>

This will make the ListBox control as tall as needed to display all its elements, pushing the button after the ListBox's last item.

Note that this may impact the performances of your application if there are lots of items in the list.

As suggested by Wouter, you should also remove the MaxHeight properties from the StackPanel and ListBox, as the only height constraint you want is the one on the top-level ScrollViewer.

Andréas Saudemont
How would I do this, and still be able to use my ItemsTemplate (listed in the question)?
froeschli
A ListBox's ItemTemplate is different from the ListBox's Template. You can use both at the same time. In your case, just insert <ListBox.Template>...</ListBox.Template> into your XAML (and keep your ListBox.ItemTemplate as it is). Hope this helps.
Andréas Saudemont
Updated the XAML to include the ControlTemplate.
Andréas Saudemont
Tried this, but upon removing the fixed height I loose scroll functionality.
froeschli
A: 

Hi Froeschli,

Baba demonstrates use of ItemsPresenter and Button in a ListBox control template to accomplish a "More" button at the end of the list in this answer:

http://social.msdn.microsoft.com/Forums/en-US/windowsphone7series/thread/cdf2716d-0ceb-4c03-9e26-cbe9f53328d8

Mick N
A: 

There is a blog post about detecting when the last item on a list is scrolled in to view at http://blog.slimcode.com/2010/09/11/detect-when-a-listbox-scrolls-to-its-end-wp7/

Could you use this technique to dynamically add your button to the screen? If needed, you could remove it again when the list is scrolled.

Just a thought.

Matt Lacey
Seems like the answer I am looking for. I am in over my head with custom DependancyProperties, so I will have talk this over with my coach. Thanks for the lead! I will let the bounty run for another day or so, but after that, I am apt to award you the bounty!
froeschli