ListBox.SelectedIndex in ContextMenu event handler - windows-phone-7

I have a listbox with context menu. How can I get value of SelectedIndex (SelectedItem) property in ContextMenuItem click event handler? Currently in events Edit_Click and Delete_CLick a value of CarsList.SelectedIndex always is -1.
Here my ListBox in XAML:
<ListBox Name="CarsList" Style="{StaticResource ListBoxStyle}" Margin="26,0,26,0" Height="380" >
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu Name="ContextMenu" >
<toolkit:MenuItem Name="Edit" Header="Edit" Click="Edit_Click"/>
<toolkit:MenuItem Name="Delete" Header="Delete" Click="Delete_Click"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding CarName}" TextTrimming="WordEllipsis" Foreground="Black" FontSize="24" Width="428"/>
<TextBlock Text="{Binding VIN}" TextWrapping="Wrap" Foreground="Gray" FontSize="20" Width="428"/>
<TextBlock Text="{Binding Date}" TextWrapping="Wrap" Foreground="Gray" FontSize="20" Width="428"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Thanks.

First of all you have assigned Context Menu to ListBox control, not an each item. So, move <toolkit:ContextMenuService.ContextMenu> block to StackPanel instead.
There are several ways to get element, on which context menu click was performed:
In Click handler you have sender object (it is MenuItem, I guess)
Cast it to MenuItem and look to DataContext of it. It will be item of collection you binded to a list. So, you can find index by:
int selectedIndex = YourListBoxItemCollection.IndexOf((sender as MenuItem).DataContext)
, where YourListBoxItemCollection is what you assign to CarsList.ItemsSource

Looks like you need to use ListPicker (http://silverlight.codeplex.com/releases/view/75888) with SelectedItems.
OR
Add some flag of element selection...

Related

Cannot fire event on non-text region when tap&hold to show the contextmenu in WP7

I want to add the context menu to ListBox in WP7, I modify the data template as following below:
<ListBox Name="lbx1" Margin="10,0,10,0" Height="435" ItemContainerStyle="{StaticResource ListBoxItemStyle1}" FontSize="40" Tap="lbx1_Tap" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="Copy" Click="ListBoxGeneralCopy_Click"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<TextBlock Text="{Binding .}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I can only cause tap and hold event to show the contextmenu above the text, the non-text region could not cause the event, I really confused. Does someone can help me?
Your textbloc will only occupy so much space as necessary. Therefore your stackpanel will also only be as wide as necessary.
You can set the HorizontalAlignment-value of both to stretch so it occupies the whole width:
<ListBox Name="lbx1" Margin="10,0,10,0" Height="435" ItemContainerStyle="{StaticResource ListBoxItemStyle1}" FontSize="40" Tap="lbx1_Tap" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Stretch">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="Copy" Click="ListBoxGeneralCopy_Click"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<TextBlock Text="{Binding .}" HorizontalAlignment="Stretch"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Set StackPanel background property.
When background is transparent cannot work, and hold event is fired only in non-transparent region of stackpanel such as text-regions.

how context menu opens in listbox wp7

I have a list box in which when i long-press the particular item of the listbox, a context menu opens. But in the listbox i have not used tap or hold event of listbox so how my context menu is visible.
Please tell which event is firing which opens my context menu; the xaml code is:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox x:Name="scheduleListbox" ItemsSource="{Binding scheduleList}" Tap="scheduleListbox_Tap">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Height="150" Width="460">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu >
<toolkit:MenuItem Header="Add To Calendar" Click="AddToCalendar_Click" />
<toolkit:MenuItem Header="View Description" Click="ViewDescription_Click" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<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">
<TextBlock x:Name="textBlock3" Text="{Binding StartTime}" Margin="0,5,0,0"/>
<TextBlock x:Name="textBlock4" Text="{Binding EndTime}" Margin="50,5,0,0"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Please tell how my context menu is open as i haven't used tap or hold event of listbox but when I long-press the listbox item, the context menu opens?
By default, the context menu opens on long hold, it is by design. If you wish to open it any other way, you must write your own logic. For examples on how to do that, see these threads:
Setting a ContextMenu to open on “Tap” causes ContextMenu to open up at the top of the screen
ContextMenu on tap instead of tap and hold
But be aware that some users might be confused by this since most users will expect that the context menu will be shown when you tap and hold the list box item.

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>

Windows Phone How to Vertical Scroll

I'm just starting out in WinPhone development and can't figure out how to set the vertical scroll. For example i've started a new Pivot App, and this code allows the user to scroll up and d own to see all the entries:
<controls:PivotItem Header="Login">
<!--Double line list with text wrapping-->
<ListBox x:Name="FirstListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Height="78">
<TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PivotItem>
Now when, I add my own pivot item, with a stackpanel with more items than can be seen on the screen at any one time, it will not allow me to scroll to see them all. What am I missing here?
Thanks.
Add ScrollViewer over the StackPanel and it will make it scrollable.
The ListBox in the example code that you supplied ha built-in scrolling functionality. However, if you are not using something that already has this scrolling functionality in it, you will have to add a ScrollViewer.
<controls:PivotItem Header="Example">
<ScrollViewer Margin="12,0,12,0">
<StackPanel>
<TextBlock Text="Example1" FontSize="150" />
<TextBlock Text="Example2" FontSize="150" />
</StackPanel>
</ScrollViewer>
</controls:PivotItem>
In a pivot control, if the content is overflowing the vertical page then there should be default "vertical" scrolling available to you.
I had a similar control with list box bounded to property. Having "list" should automatically allow you to scroll.
Don't add a scrollviewer over the stack panel as it would make the scrolling enabled for each list item which you don't want.
<controls:PivotItem Header="all authors" Foreground="#FF0C388A">
<Grid>
<ListBox Margin="0,0,-12,0" ItemsSource="{Binding AllAuthorsList}" Foreground="#FF0C388A">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Height="Auto">
<TextBlock Tap="TextBlockAuthor_Tap" Text="{Binding}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}" Foreground="#FF0C388A"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</controls:PivotItem>

listbox item click event?

i binded some items to listbox.whenever click on particular listitem i want to display that subitems in another page.
Please tell me how to acheive this.
how to get the listitem id whenever click on particular list item ?
To clarify (in case you don't feel like creating a new DataBound application and just want the answer), instead of depending on the click event for a listbox item, you should be looking at the selectionchanged event for the list box itself.
eg:
<ListBox SelectionChanged="MainListBox_SelectionChanged">
// Handle selection changed on ListBox
private void MainListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// If selected index is -1 (no selection) do nothing
if (MainListBox.SelectedIndex == -1)
return;
// Navigate to the new page
NavigationService.Navigate(new Uri("/DetailsPage.xaml?selectedItem=" + MainListBox.SelectedIndex, UriKind.Relative));
// Reset selected index to -1 (no selection)
MainListBox.SelectedIndex = -1;
}
Look at the code created as part of a new DataBound application. It does just this.
MVVM solution
Use the following libraries:
xmlns:GalaSoft_MvvmLight_Command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP71"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit" <-- (optional, only for the ContextMenu)
XAML Example:
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox x:Name="categoryListBox" Margin="0,0,-12,0" ItemsSource="{Binding CategoryItems}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="stackPanel" Margin="0,0,0,17" Width="432" Height="78">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<GalaSoft_MvvmLight_Command:EventToCommand
Command="{Binding Main.OpenCategoryCommand, Source={StaticResource Locator}, Mode=OneWay}"
CommandParameter="{Binding Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="Remove" />
<toolkit:MenuItem Header="Show" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<TextBlock Text="{Binding Name}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding Note}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
For a simple command binding MVVM style to an item in a list, you can also enclose the whole item template in a button and hook up the Command property of the button like this:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Button Command="{Binding Path=SomeCommandOnItemViewModel, Mode=OneWay}">
<Button.Template>
<ControlTemplate>
<!-- Your listitem styling goes here -->
</ControlTemplate>
</Button.Template>
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>

Resources