0

I am trying to add pinch to zoom feature to a data bound ListBox. What is the most efficient way to do this? I have placed the ListBox inside a Grid control and made it scrollable.

This is my current code.

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="10,0,10,10" Background="Black" >
        <ListBox Name="lstText" FontSize="24"  Foreground="White" SelectionMode="Single" Margin="10,0,10,10"  ScrollViewer.VerticalScrollBarVisibility="Visible"  >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel >
                        <TextBlock Text="{Binding Text}" TextWrapping="Wrap"></TextBlock>                           
                    </StackPanel>                        
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
    <toolkit:GestureService.GestureListener>
        <toolkit:GestureListener 
            Tap="GestureListener_Tap" 
            PinchCompleted="GestureListener_PinchCompleted"
            Flick="GestureListener_Flick">

        </toolkit:GestureListener>
    </toolkit:GestureService.GestureListener>
Daniel
  • 1
  • 1

3 Answers3

1

The Listbox isn't designed to be zoomed (via pinching or any other method).

If you want to implement this you must redraw the content at the different zoom levels.
You'd have a number of issues to overcome though:

  • How do you inform the user that they can alter the text size this way?
  • How do you avoid affecting the standard behaviour for scrolling and selecting items in the listbox.
  • How should scrolling behave with regard to wrapping and the currently shown text?
  • A list shouldn't be used to show large amounts of text on a phone. If you need to show a large amount of text, have a short "title" in the list and then show the detail in another page. This way the text in the list can always be displayed in a way that is large enough that it never need changing and should always be readable.
  • Is this a genuine problem you are trying to overcome or just something you think would be nice to have? The phone won't be used for just your app so why do you need this if the user will still have to use lists with a fixed text size in the OS and other apps.
  • You'd have potential performance issues with performance as the framework redraws everything in the list when you change the size of the text. You could look at use deferred loading to only have to redraw what is shown on the screen while zooming but this will impact how you determine the top (and bottom) of what is shown as the sizes change.

Summary: This is almost certainly unnecessary and will be very complicated and difficult to do well. If you really want to try this have a go and then post code with any problems.

Matt Lacey
  • 65,560
  • 11
  • 91
  • 143
  • Thanks for your response. By Text zoom i meant, it should increase and decrease the font size of the content inside the ListBox. So can you point me to a code sample? – Daniel Dec 20 '10 at 16:25
  • I am displaying verses from bible in this listbox, However I would like to keep the scrolling feature so users can scroll through the verses of a selected chapter. Not sure if this clarifies the concept. – Daniel Dec 20 '10 at 17:34
  • @Daniel You don't need a Listbox just to get scrolling. Just wrap the text in a ScrollViewer. – Matt Lacey Dec 20 '10 at 17:46
  • I Understand, but what is the best control to list text, each sentence as one line item other than listbox? And how will I implement pinch to zoom the text on that control? – Daniel Dec 20 '10 at 18:02
0

I've done this myself with manipulationDelta but it's not smooth at all

In the class attributes

 x:local="clr-namespace:YourApplicationNamespace"

In the XAML:

<Grid x:Name="LayoutRoot"  ManipulationDelta="LayoutRoot_ManipulationDelta">
   <Grid.Resources>
       <local:CustomSettings x:Key="Settings"/>
       <DataTemplate x:Key="verseDataTemplate">
          <TextBlock FontSize="{Binding Path=Font35, Source={StaticResource Settings}}" 
                     Text="{Binding}"/>
       </DataTemplate>
   </Grid.Resources>
   <ListBox ItemTemplate="{StaticResource verseDataTemplate}"/>

in the code behind:

private void LayoutRoot_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
    {
        try
        {
            var fnt = lboVerses.FontSize;
            if (e.DeltaManipulation.Scale.X == 0 || e.DeltaManipulation.Scale.Y == 0) return;
            if (e.DeltaManipulation.Scale.X > 1 || e.DeltaManipulation.Scale.Y > 1)
            {
                if (fnt < 72)
                   BibliaSettings.font35++;
            }
            else if (e.DeltaManipulation.Scale.X < 1 || e.DeltaManipulation.Scale.Y < 1)
            {
                if (fnt > 5)
                    BibliaSettings.font35--;
            }
        }
        catch (Exception x)
        {
            Debugger.Log(0, "Errors", x.Message + "\n" + x.StackTrace);
        }
    }

Your CustomSettings class

public class CustomSettings : INotifyPropertyChanged
{
    public static List<CustomSettings> Instances;
    public CustomSettings()
    {
        if (Instances == null) Instances = new List<CustomSettings>();
        Instances.Add(this);
    }
    public static int font35
    {
        get 
        {
            return Get("Font35", 35); //Provide mechanism to get settings
        }
        set
        {
            Save(value, "Font35");//Provide mechanism to store settings
            Instances.ForEach(inst => inst.OnPropertyChanged("Font35"));
        }
    }
    public int Font35
    {
        get
        {
            return font35;
        }
        set
        {
            font35=value;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
csharpwinphonexaml
  • 3,659
  • 10
  • 32
  • 63
0

Alex Yakhnin offers a solution for scrolling long text.

Creating Scrollable TextBlock for WP7. - Alex Yakhnin's Blog

You can wrap a TextBlock in a ScrollViewer which may be sufficient for your needs. If your text is long enough you will hit a variety of walls as the text gets larger in size. Alex's solution is a control which wraps a StackPanel in a ScrollViewer and adds TextBlocks to the StackPanel in manageable sections.

Mick N
  • 14,892
  • 2
  • 35
  • 41
  • I am looking for a pinch to zoom solution for the text control. not matter if its listbox or textblock. But i want to use ListBox as i have more than one row of data to show. I hope this makes it clear. – Daniel Dec 21 '10 at 03:08
  • Sure, you can use listbox to scroll textblocks, however there is a catch. Listbox will not do display virtualisation with listboxitems that are of variable height. I am curious what feature(s) of listbox you're attached to that make you set on this control for display text. I'm also curious what it is you want pinch and zoom to do for you. – Mick N Dec 21 '10 at 08:36
  • I am using ListBox to display multiple rows from the Database. So user can interact with each individual item. – Daniel Dec 21 '10 at 14:14
  • And pinch to zoom should increase/decrease the font size of the contents inside the ListBox. – Daniel Dec 21 '10 at 14:15
  • You might find this easier to implement using another control (ie. a slider) to control the listbox font size. – Mick N Dec 22 '10 at 04:21
  • Here's another option you can check out for pinch control of zooming. http://soonstudios.wordpress.com/2010/12/26/simple-center-zoom/ – Mick N Dec 28 '10 at 11:12