I have a Listbox with Button and Textblock as ItemTemplate. Button has an onClick event.
All i want is to get the index of the clicked item, but SelectedIndex property in my ListBox is always -1!
How can I get the index of the clicked item?
The problem is that the Button control is swallowing the mouse events to provide the Click behavior, so the ListBox never receives any events to tell it that the selection has changed.
As #Alexander suggests, you could use an MVVM-style approach with commands to handle the action in a view model and pass the data context as the parameter.
Alternatively, you could replace the Button with any other layout control and either use the gesture service from the Silverlight Toolkit or use the regular MouseLeftButtonUp event. In either instance, the mouse events will bubble up and enable the ListBox to handle selection.
You might want to actually select something in your listbox then :p
If you want to get data object associated with current ListItem use RouteCommand. Here is example
<ListView.ItemTemplate>
<DataTemplate>
<Button Margin="5,0" Command="{StaticResource ButtonCommand}"
CommandParameter="{Binding}">
</DataTemplate>
<ListView.ItemTemplate>
You need also define Command at least in ListView.Resources
<RoutedCommand x:Key="ButtonCommand"/>
And then setup CommandBinding like this
<ListView.CommandBindings>
<CommandBinding Command="{StaticResource ButtonCommand}" Executed="Button_Click"/>
</ListView.CommandBindings>
In the end write handler
Button_Click(object sender, ExecutedRoutedEventArgs e)
{
e.Parameter// object that you Specified in CommandParameter
}
In advance you can use any MVVM framework, define all command and commands logic in model and then just bind this commands to corresponding elements.
Related
I am having issues with using a ContextMenu within a ListBox. One of the items of my ContextMenu is used to pass the name of the item via querystring to another page in my application. As of now I am using the SelectionChanged event of my ListBox to retrieve the name of the item selected, but this requires that the user press and then release the item to register the event. I would like to be able to get the name of the item pressed when the user presses a ListBox item down to access the ContextMenu, without pressing up.
To Note, I have tried using the KeyDown event of the ListBox for this purpose, but it did not work either. What event can I use to meet this requirement?
If you are using the binding in listbox for listbox item the you can use Tag Property of MenuItem of ContextMenu.
To Bind the tag use
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu Background="{StaticResource PhoneChromeBrush}">
<toolkit:MenuItem Foreground="{StaticResource PhoneForegroundBrush}" Header="Send" Name="Send" Tag="{Binding Name}" Click="Send_Click_1"/>
</toolkit:ContextMenuService.ContextMenu>
When you click on ContextMenuItem you can access the Tag using
var name = ((MenuItem)sender).Tag.ToString();
You can access listbox item by using this statement if you are using binding property
var listBoxItemName= ((MenuItem)sender).DataContext as ListBoxItemClass;
Here, ListBoxItemClass is the name of tha class you used for bind the property.
Try this, hope you get what you want
Using MVVM Light I have a listbox databound to a collection of several items.
One of the items is the selected one.
With this code it works perfectly and ViewModel structures are updated correctly:
<Name="listBox1"
ItemsSource="{Binding Path=Models}"
SelectedItem="{Binding Path=csProfile.Model, Mode=TwoWay}">
My problem is that when I enter the page if the selected Item is not in the first items it is not visible and the user does not know what was the previous selection.
How could I force the Listbox to always show the Selected Item?
Possibly via properties or Binding.
M
There's no property you can bind to to set what's visible. Instead call ScrollToVerticalOffset() on the ScrollViewer inside the ListBox.
I think you are looking for the ScrollIntoView method. A similar topic was discussed here:
Automatic Scrolling in a Silverlight List Box
The API reference is here: http://msdn.microsoft.com/en-us/library/system.windows.controls.listbox.scrollintoview(VS.95).aspx
Calling UpdateLayout() before calling ScrollIntoView on the selected item seems to be necessary.
I had a quick question on working with listboxes in WP7 using MVVM Light. Basically before I was using MVVM all I had to do was set the SelectedIndex to -1 inside of the OnNavigatedTo event when the page was navigated to. Then inside of the SelectionChanged event I would check if the SelectedIndex was equal to -1 and if so I would ignore it. The reason I did this was just in case the user wanted to select the same item again when they came back to the page.
Now with MVVM (MVVM Light) I'm binding the event to a command, which takes care of the first part. But now I'm stuck because I don't know how to set the SelectedIndex to -1 from the ViewModel which prevents the user from selecting the same item again. Any ideas?
An even better solution is to not use the selection event to trigger a navigation. Use the tap event of the indivdual item instead.
This also avoids issues of accidental navigation when scrolling.
Try creating a SelectedItem property on your viewmodel, then do a two-way between the SelectedItem viewmodel property and the SelectedItem property on your ListBox. Then you can update it with whatever value you want when your Command fires and the result will propagate back to your ListBox.
I am using a listbox in a data template - and from an earlier post I cannot reference the listbox directly in the code behind.
As a result I am capturing the last selected object in the selectionchanged event for the listbox and using this when I want to navigate.
I now need to also clear the selected object in the listbox -can I do this in the selectionchanged event (after storing it away).
Alternatively I could use the MouseLeftButtonDown event on the listbox (which I understand is the equivalent of a 'click') but can I get the selected object in the listbox in this event.
thanks
In the selection changed event set <ListboxName>.SelectedIndex = -1;
Also, do not use the MouseLeftButtonDown event. This will fire whenever the user touches the ListBox, even if they're just trying to scroll up / down and not actually selecting an item.
If you can't change the SelectedIndex in code behind then, instead of detecting the SelectionChanged event you could detect a Tap event on the ListBoxItem.
I've read somewhere that longlistselector from the toolkit is better in performance than the existing listbox. So, I changed the listbox to longlistselector. Now I have a image button control to keep in the longlistselector (that acts like a checkbox). When I click on the button, the list selection changed event is fired along with the button click. The button in listbox works fine as expected but not in longlistselector. How can I stop the list selection changed event? I searched a lot on this but couldn't find anything useful. First of all is it possible?
I wouldn't take it for granted that the long list selector performs better than the listbox. The listbox uses a virtualizing stack panel when binding is involved and is pretty performant. I went down the road of using the list picker from the toolkit and ended up regretting it due to some bad performance problems. If it works with the listbox I'd say stick with the listbox and only move away if you find you have perfomance issues in the future.
When a button is clicked a button event handler is triggered and when a item in the long list selector is changed the corresponding selection changed event is triggered IF it is also registered. But the button is clicked on the same selected item, only the button event handler is triggered. I suggest to have only a button event handler and get the selected item from it.
private void ButtonEvent_Click(object sender, RoutedEventArgs e)
{
HoldingClass clicked=((sender as Button).DataContext as HoldingClass);
//Do something with the HoldingClass as this is the binding element to the long list selector
}
Change the ClickMode to Press in XAML
ClickMode="Press"
and inside you Click event handler make (YourListName).SelectedItem = null;
private void deleteButton_Click(object sender, RoutedEventArgs e)
{
MainLongListSelector.SelectedItem = null;
..
}