ListBox OnSelectionChanged event stops working with "many" items - windows-phone-7

I noticed a very strange behavior:
in my windows phone 7 I have a ListBox that can contain anything from 1-2 to 2-300 items.
I noticed that when the number of items is big (not sure about the number but for sure >150 items) the OnSelectionChanged event is not raised.
This is the XAML of my listbox
<ListBox ItemsSource="{Binding Path=Posts}" ItemTemplate="{StaticResource IconsWithText}"
ScrollViewer.VerticalScrollBarVisibility ="Disabled"
SelectionChanged="ListBox_SelectionChanged" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
And the template for the ItemTemplate is:
<DataTemplate x:Name="IconsWithText">
<Grid x:Name="ThumLink" Width="160" Height="140" Margin="10" Background="#FF666666">
<Image Source="Resources/Images/All.png" Visibility="{Binding Path=VisibilityAll}" />
<Image delay:LowProfileImageLoader.UriSource="{Binding Picture}"
Visibility="{Binding Path=VisibilityPic}"
Stretch="UniformToFill" VerticalAlignment="Top" HorizontalAlignment="Left" />
<Border x:Name="border" VerticalAlignment="Bottom" Background="#d9ffffff" Height="62" BorderBrush="Black" Visibility="{Binding Path=VisibilityPic}" >
<TextBlock x:Name="textBlock" Text="{Binding Title}" VerticalAlignment="Top" TextWrapping="Wrap" MaxHeight="60" Style="{StaticResource PhoneTextSmallStyle}"
Foreground="Black" FontSize="20" Margin="4,1,4,0" Height="62"/>
</Border>
</Grid>
</DataTemplate>
Is this a bug or did I do something wrong? I was in debug and the event handler never gets called, but it works when the items are not many.
Simone

The problem with using the plain StackPanel is that all visual object will be created and added to the StackPanel which will be very expensive in terms of memory and may trip over other limits in the rendering system.
Try changing to:-
<VirtualisingStackPanel Orientation="Horizontal" />
So far though I've not been able to reproduce your problem with 300 items even using a plain StackPanel.

Related

Silverlight ListBox does not scroll on mouse wheel movement on Mac

I have Silverlight based web app where. I found the ListBox doesn't scroll on mouse wheel scroll. I am able to scroll by clicking vertical scroll bar. When I use mouse wheel or 2 finger scroll it doesn't work.
Here in Mouse Wheel scroll in List box 2 is working fine but ListBox 1 it does not work.
ListBox 1
<Border CornerRadius="6,6,0,0" Grid.Row="1" Margin="2,5,2,0" BorderThickness="1,1,1,0" BorderBrush="#FFC4C4C4">
<Grid>
<ListBox x:Name="filterListBox" Grid.Row="0" Grid.Column="1" Background="Transparent" SelectedIndex="{Binding SelectedFilterIndex, Mode=TwoWay}" SelectedItem="{Binding SelectedFilterItem, Mode=TwoWay}" SelectionChanged="ListBox_SelectionChanged" BorderThickness="0" VerticalAlignment="Center" Margin="5,3" ItemContainerStyle="{StaticResource FilterListBoxItemStyle}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<ei:CallMethodAction TargetObject="{Binding}" MethodName="FilterSelectionChanged"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem Padding="7,2" VerticalContentAlignment="Center" Tag="Popular" Visibility="{Binding Path=IsPopularChannelTab, Mode=TwoWay, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock Text="{Binding Path=PopularChannelsText, Source={StaticResource PageStrings}}" FontSize="13" FontWeight="SemiBold" FontFamily="Arial" VerticalAlignment="Center" />
</ListBoxItem>
<ListBoxItem IsEnabled="False" VerticalContentAlignment="Center" Visibility="{Binding Path=IsPopularChannelTab, Mode=TwoWay, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Orientation="Horizontal">
<Border BorderBrush="#FFBDBDBD" BorderThickness="0,2,2,2" HorizontalAlignment="Center" VerticalAlignment="Center" Height="20"/>
<Border BorderBrush="#FFF8F8F8" BorderThickness="0,2,2,2" HorizontalAlignment="Center" VerticalAlignment="Center" Height="20"/>
</StackPanel>
</ListBoxItem>
<ListBoxItem Padding="7,2" VerticalContentAlignment="Center" Tag="All">
<TextBlock Text="{Binding Path=AllChannelsText, Source={StaticResource PageStrings}}" FontSize="12" FontWeight="SemiBold" FontFamily="Arial" VerticalAlignment="Center"/>
</ListBoxItem>
<ListBoxItem IsEnabled="False" VerticalContentAlignment="Center">
<StackPanel Orientation="Horizontal">
<Border BorderBrush="#FFBDBDBD" BorderThickness="0,2,2,2" HorizontalAlignment="Center" VerticalAlignment="Center" Height="20"/>
<Border BorderBrush="#FFF8F8F8" BorderThickness="0,2,2,2" HorizontalAlignment="Center" VerticalAlignment="Center" Height="20"/>
</StackPanel>
</ListBoxItem>
<ListBoxItem Padding="7,2" VerticalContentAlignment="Center" Tag="Favorites">
<TextBlock Text="{Binding Path=FavoritesText, Source={StaticResource PageStrings}}" FontSize="13" FontWeight="SemiBold" FontFamily="Arial" VerticalAlignment="Center"/>
</ListBoxItem>
</ListBox>
</Grid>
</Border>
ListBox 2
<Grid Visibility="{Binding Path=IsHavingProvider, Converter={StaticResource BoolToVisibilityConverter}}" Margin="0,20,0,0" Grid.Row="4">
<Grid.RowDefinitions>
<RowDefinition Height="18"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<core:MagicTextBlock Grid.Row="0" TextBlockStyle="{StaticResource TextBlock_Style}" Text="{Binding Path=Activity, Source={StaticResource PageStrings}}" />
<ListBox Margin="0,10,0,0" Grid.Row="1" x:Name="Provider" Width="480" Height="195" HorizontalAlignment="Left" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Providers,Mode=TwoWay}"
SelectedItem="{Binding SelectedProvider,Mode=TwoWay}"
ItemContainerStyle="{StaticResource Table_ListBoxItem_Style}"
DisplayMemberPath="name">
</ListBox>
</Grid>
Sorry to be the bearer of bad news:
Some current mouse devices for Macintosh have a physical or virtual
mouse wheel. However, the program access layer used by Silverlight on
Macintosh does not support forwarding the mousewheel event to
Silverlight in a browser-hosted situation. You can handle the
Silverlight MouseWheel event from a Macintosh platform client, if the
Silverlight application is running out-of-browser. Otherwise, consider
handling mousewheel events for Macintosh platform at the HTML DOM
level; for more information, see Platform Dependencies.
From the MSDN Silverlight Differences on Windows and Macintosh.
The good news is you can listen to the mousewheel events in the HTML page via JavaScript and pass those events into Silverlight via its JavaScript interop API. The additional bad news is I don't know of a way to have it automatically wire into the GUI elements in your application to have them automatically just work (like scrolling list boxes in your case). As far as I know, you'd have to manually listen to it, pick up on which object the user is hovering over with their mouse, and programmatically scroll the GUI component.

Binding to a Collection of Checkboxes

I'm trying to do some XAML binding for the Windows Phone (targeting WP7.1) and I have a collection of checkboxes that I want to display. I want to put them inside the WrapPanel
What control(s) would I use to bind to a collection of checkboxes? I don't see an ItemSource for the WrapPanel. So I'm not sure what I would use.
<ListBox Height="auto" Name="lbAssignments" BorderThickness="1" BorderBrush="Black" ItemsSource="{Binding DataList}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock x:Name="TextBlock" Text="{Binding Title}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,0,0,10" FontSize="26.667" TextWrapping="Wrap"/>
<TextBlock x:Name="TextBlock1" Text="{Binding Title}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,0,0,10" FontSize="26.667" TextWrapping="Wrap"/>
<toolkit:WrapPanel Height="400" Width="400">
<!--collection of checkboxes-->
</toolkit:WrapPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Binding to a collection of UI controls is not exactly the thing you'd want to do. Instead, I would recommend binding to a collection. For many reasons - performance, memory allocation and general maintenance/flexibility.
Since you mentioned that you have a List<string>, you can just bind it to a ListBox:
<ListBox ItemsSource="{Binding YourList}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding}"></CheckBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
However, you can still proceed with biding an element to a collection of other elements, given that appropriate support exists. You could use an ItemsControl:
<ItemsControl ItemsSource="{Binding ElementName=myPage, Path=SomeCollection}">
</ItemsControl>
Here, SomeCollection might as well be ObservableCollection<CheckBox>.

How to Bind data in context menu WP7

I have a list in which there are schedule name, date and time that are visible, but i want that on the long press of a particular item in a listbox there opens a context menu in which only description and schedule name of particular item is visible.
So my code in xaml is: first in the grid there is a listbox in which i have bound the whole list that is scheduleList ansd in the listbox.itemtemplate and inside the data templatei have binded the particular item to the textblock
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox x:Name="scheduleListbox" ItemsSource="{Binding scheduleList}" Hold="scheduleListbox_Hold" Tap="scheduleListbox_Tap" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Height="150" Width="460">
<TextBlock x:Name="textBlock1" Text="{Binding ScheduleName}" Foreground="WhiteSmoke" FontSize="32"/>
<TextBlock x:Name="textBlock2" Text="{Binding ScheduleDate}" Foreground="Red" Margin="0,10,0,0"/>
<StackPanel Orientation="Horizontal" Height="70" Width="460" Hold="StackPanel_Hold">
<TextBlock x:Name="textBlock3" Text="{Binding StartTime}" Margin="0,5,0,0"/>
<TextBlock x:Name="textBlock4" Text="{Binding EndTime}" Margin="50,5,0,0"/>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu x:Name="menuItem" VerticalOffset="100.0" IsZoomEnabled="True" >
<toolkit:MenuItem Header="Add to calender" ItemsSource="{Binding ScheduleName }"/>
<!--<toolkit:MenuItem Header="Description" ItemsSource="{Binding Description}"/>-->
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Please tell me that how to bind description and schedule name in context menu, either by code or by xaml.
How to bind data in context menu either through code or through xaml?
I create a breadcrumb context menu with binding using the code below. The code you should be interested in is the toolkit:ContextMenu.ItemTemplate section where you specify the bindings. Notice that you can also bind to a command parameter like I do with the index value.
The toolkit:ContextMenu.Template section is not needed. I added this to allow scrolling the items if there are more than will fit on the screen and also to move the menu to the bottom of the screen.
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu x:Name="breadCrumbContextMenu" ItemsSource="{Binding CloudViewModel.BreadCrumbMenuItems}" Opened="ContextMenu_Opened" Closed="Breadcrumb_ContextMenu_Closed">
<toolkit:ContextMenu.Template>
<ControlTemplate TargetType="toolkit:ContextMenu">
<Border Margin="0,700,0,0" BorderThickness="1" >
<ScrollViewer MaxHeight="700">
<ItemsPresenter/>
</ScrollViewer>
</Border>
</ControlTemplate>
</toolkit:ContextMenu.Template>
<toolkit:ContextMenu.ItemTemplate>
<DataTemplate>
<toolkit:MenuItem Click="breadcrumbMenuItem_Click" CommandParameter="{Binding Index}" Padding="0">
<toolkit:MenuItem.Header>
<StackPanel Orientation="Horizontal" Height="40">
<Image Source="{Binding Image}" Width="40" Height="40" />
<TextBlock Text="{Binding Text}" Margin="24,0,0,0" />
</StackPanel>
</toolkit:MenuItem.Header>
</toolkit:MenuItem>
</DataTemplate>
</toolkit:ContextMenu.ItemTemplate>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>

ListBox Style Selected item on windows phone

i would like know how can i add a style when a item of the listbox is selected.
I have the following listbox:
<ListBox x:Name="ListBoxDays"
VerticalAlignment="Top"
ItemTemplate="{StaticResource WeekDayTemplate}"
ItemsSource="{Binding WeekDayList}" />
And i also have a DataTemplate to the listbox.
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="WeekDayTemplate">
<StackPanel x:Name="stackPanel" Orientation="Horizontal" Width="400" Margin="12,0,0,10" Height="100" >
<StackPanel VerticalAlignment="Center" Orientation="Vertical">
<TextBlock Text="{Binding WeekDayName}" Style="{StaticResource PhoneTextExtraLargeStyle}" TextWrapping="Wrap" TextTrimming="WordEllipsis" Foreground="{StaticResource PhoneRadioCheckBoxPressedBorderBrush}" UseLayoutRounding="True" />
<TextBlock Text="{Binding ShortDate}" Style="{StaticResource PhoneTextTitle2Style}" TextWrapping="Wrap" TextTrimming="WordEllipsis" Foreground="{StaticResource PhoneBorderBrush}" Margin="25,0,12,0" />
</StackPanel>
</StackPanel>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
At the moment when i select an item of the listbox no color change happens.
You have to change the style of the template ListBoxItem which the ListBox generates for each of the items that it renders. Your updated template needs to customise the Selected visual state. You can then associate this new template with your ListBox via the ListBox.ItemContainerStyle property.
There is a good tutorial, with sourcecode to download, here:
http://windowsphonegeek.com/tips/How-to-customize-the-WP7-ListBox-Selected-Item--Part1-Control-Template

Scroll PanoramaItem Header in 'wide' PanoramaItem

I'm interested in creating my own 'Hub' Panorama. I've gotten the 'wide' PanoramaItem working, but I'm trying now to mimic the behavior seen in the Marketplace hub, where the PanoramaItem Header scrolls as you move across the hub.
I'm looking for a way for it to smoothly animate to the end of the hub. Has anyone tried this before, or have any suggestions?
I'd imagine it would be something like this:
//OnPanoramaViewChanged
//get X location of viewport
//animate title to X location
However it doesn't appear that the Panorama has a ScrollViewer attached property.
In case you're curious, here's how I made a wide panorama item.
<controls:PanoramaItem ScrollViewer.HorizontalScrollBarVisibility="Visible" Header="movies" Orientation="Horizontal" Width="900">
<controls:PanoramaItem.HeaderTemplate >
<DataTemplate >
<StackPanel>
<TextBlock Foreground="{StaticResource PanoramaHeaderBrush}" Text="{Binding}">
</TextBlock>
</StackPanel>
</DataTemplate>
</controls:PanoramaItem.HeaderTemplate>
<StackPanel>
<!-- line list with image placeholder and text wrapping -->
<ListBox ItemsSource="{Binding Items}" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Template>
<ControlTemplate>
<ItemsPresenter />
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10">
<Grid Background="{StaticResource ControlTitlesInactivePivotBrush}" Width="173" Height="173" >
<TextBlock FontSize="24" Text="Movie Title (2010)" TextWrapping="Wrap" Style="{StaticResource PhoneTextGroupHeaderStyle}"/>
<Rectangle Fill="White" Height="48" Width="48" HorizontalAlignment="Right" VerticalAlignment="Bottom">
<Rectangle.OpacityMask>
<ImageBrush ImageSource="/Test;component/movie_icn.png" />
</Rectangle.OpacityMask>
</Rectangle>
</Grid>
<TextBlock Text="Movie Title:" Margin="12,0,12,0" Foreground="Black" />
<TextBlock Text="The Title" Margin="12,-6,12,0" Foreground="Gray"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</controls:PanoramaItem>
The Silverlight Panorama control doens't support the behaviour you're after or provide the ability to customize it in a way that will let you do it.
If you really want this then you'll need to build your own control from scratch. I would expect this to be more effort than is justified. Just avoid creating a very wide PanoramaItem instead.

Resources