windows phone listbox - windows-phone-7

1) This is my code for listbox2 selectionchanged
void PrintText2(object sender, SelectionChangedEventArgs args)
{
if (null != listBox2.SelectedItem)
{
ListBoxItem lbi = ((sender as ListBox).SelectedItem as ListBoxItem);
textBlock4.Text = lbi.Content.ToString();
}
}
2) This my code for listbox1 selecionchanged
void PrintText1(object sender, SelectionChangedEventArgs args)
{
if (null != listBox1.SelectedItem)
{
ListBoxItem l = ((sender as ListBox).SelectedItem as ListBoxItem);
textBlock6.Text = l.Content.ToString();
if (textBlock6.Text == "Angle")
{
loadlistAngle();
}
}
}
3)
void loadlistAngle()
{
listBox2.Items.Clear();
listBox2.Items.Add("Radian");
listBox2.Items.Add("Degree");
}
4) listbox1 contains static item "Angle" and on selection of "Angle" at runtime,Angle gets loaded in textBolck6 and then new items "radian" and " degree" gets added to listbox2
5) after this when I click "radian" of listbox2 ,the "radian value doesn't get loaded into textblock4 ,it gives "NullReferenceException" in "lbi.Content.ToString()"
6) how do I modify my code so that at runtime "radian" value get loaded in textblock4 and new items generated will get selected in listbox2

Run your code in the debugger after adjusting it the following way:
Where you have textBlock4.Text = lbi.Content.ToString(); replace it with:
object lbiContent = lbi.Content;
if(lbiContent != null) textBlock4.Text = lbiContent.ToString();
Put a break point at the object line. This way you will know what exactly is the contents of your listboxitem, and if it is null.
Most likely you are just placing something wrong in
listBox2.Items.Clear();
listBox2.Items.Add("Radian");
listBox2.Items.Add("Degree");
Other then that, everything is correct in the code you have provided.
Update:
Also, try substituting
ListBoxItem lbi = ((sender as ListBox).SelectedItem as ListBoxItem);
with
ListBoxItem lbi = ((sender as ListBox).SelectedItem;
You don't need to do a double cast.
And the Selected item of the list box may still be empty.
Update 2:
Most likely this shoud be how you retrieve the selected item:
ListBoxItem lbi = (args.AddedItems[0] as ListBoxItem);

Related

Xamarin - How to know what has been clicked in collection view?

I have a CollectionView with an image and a button in it. I use following code to see if somebody pressed anywhere within the cell:
private void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (((CollectionView)sender).SelectedItem != null)
{
var item = (picdata)e.CurrentSelection.FirstOrDefault();
((CollectionView)sender).SelectedItem = null;
if (allowfullscreen == "1" || allowfullscreen == "true")
{
Navigation.PushAsync(new Picture());
}
}
}
But how can I know if he clicked the button inside the cell? I was trying to do it via the Click event, but then I do not know which one of all the buttons has been clicked.
you can get the item from the BindingContext of the sender
var item = (picdata)(Button)sender.BindingContext;

ListBox and selectedIndexChanged event after the user hit the back button

In my windows phone 7 app, I have the following code to handle the OnSelectedIndexChange of a ListBox.
private void wordList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
WordList selectedList = (WordList)e.AddedItems[0];
NavigationService.Navigate(new Uri("/Views/Game.xaml?ListName=" + selectedList.Name, UriKind.RelativeOrAbsolute));
}
The above code work fine, However if the user click on the hardware back button from the Game page, and click on the same listbox item, the above code is not called. I assume this is because the selected item is the same therefore the SelectionChanged event is not being called.
How do I make it so that if the user select the same item I can still send them to the Game page?
I looked at the Tap Event but I couldn't figure out a way to get the selected Item from the tab event.
When using SelectionChanged to navigate, surround your navigation logic with a check to see if the SelectedIndex = -1. After you navigate, set the index to -1, so that the event will not fire twice.
private void wordList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var lb = sender as ListBox;
if (lb != null)
{
if (lb.SelectedIndex == -1) return;
WordList selectedList = (WordList)e.AddedItems[0];
NavigationService.Navigate(new Uri("/Views/Game.xaml?ListName=" + selectedList.Name, UriKind.RelativeOrAbsolute));
lb.SelectedIndex = -1;
}
}
This way you can get the selected Item from the Tap event.
private void wordList_Tap(object sender, GestureEventArgs e)
{
var selectedElement = e.OriginalSource as FrameworkElement;
if (selectedElement != null)
{
var selectedData = selectedElement.DataContext as WordList;
if (selectedData != null)
{
NavigationService.Navigate(new Uri("/Views/Game.xaml?ListName=" + selectedData.Name, UriKind.RelativeOrAbsolute));
}
}
}
I had such issue within a UserControl. Check the sender, and return if it is not the ListBox control which is triggering the event:
protected void cbEvents_SelectedIndexChanged(object sender, EventArgs e)
{
if (sender is DropDownList)
RebindGrid();
}

How to implement Hold in Listbox?

If hold the listbox, I want to get listbox index.
This is my code:
<ListBox Margin="0,0,-12,0"
Hold="holdlistbox"
x:Name="listbox"
SelectionChanged="listbox_SelectionChanged"
SelectedIndex="-1">
</ListBox>
private void holdlistbox(object sender, System.Windows.Input.GestureEventArgs e)
{
//How to get ListBox index here
}
If anyone knows help me to do this.
e.OriginalSource will get you the actual control that was held (the top-most control directly under your finger). Depending on your ItemTemplate and where you hold then this could be any of the controls in the item. You can then check the DataContext of this control to get the object that is bound to that item (going by your comment this will be an ItemViewModel object):
FrameworkElement element = (FrameworkElement)e.OriginalSource;
ItemViewModel item = (ItemViewModel)element.DataContext;
You can then get the index of this item in the items collection:
int index = _items.IndexOf(item);
If you want to get the ListBoxItem itself you will need to use the VisualHelper class to search the parent heirarchy. Here is an enxtension method that I use to do this:
public static T FindVisualParent<T>(this DependencyObject obj) where T : DependencyObject
{
DependencyObject parent = VisualTreeHelper.GetParent(obj);
while (parent != null)
{
T t = parent as T;
if (t != null)
{
return t;
}
parent = VisualTreeHelper.GetParent(parent);
}
return null;
}
I'm not sure if you need this (I couldn't be sure from your comment) but you can then do the following to get the context menu:
FrameworkElement element = (FrameworkElement)e.OriginalSource;
ListBoxItem listItem = element.FindVisualParent<ListBoxItem>();
ContextMenu contextMenu = ContextMenuService.GetContextMenu(listItem);
This assumes that the ContextMenu is attached to the ListBoxItem, if not then you need to search for a different control in the parent heirarchy.
var selectedIndex = (sender as ListBox).SelectedIndex;

WP7 Get listbox item text

Is there a way to get the text of a clicked listbox item?
So on click it sets a string to the text in the list box item.
In a new DataBound App, changed the following method to see 3 ways of getting this:
// 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;
var string1 = ((sender as ListBox).SelectedItem as ItemViewModel).LineOne;
var string2 = (MainListBox.SelectedItem as ItemViewModel).LineOne;
var string3 = (e.AddedItems[0] as ItemViewModel).LineOne;
// 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;
}

Selecting First Item in the ListBox on CollectionViewSource.Filter

My ListBox is Binded with CollectionView Source. When I am Changing the Filter it is Automatically selecting the First Item in the Listox.
App.ViewModel.TasksViewSource.Filter += new System.Windows.Data.FilterEventHandler(Tasks_Filter);
void Tasks_Filter(object sender, System.Windows.Data.FilterEventArgs e)
{
if (e.Item == null)
return;
Task task = e.Item as Task;
e.Accepted = task.Id.Equals(TaskId);
}
private void MainListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (TasksListBox.SelectedIndex == -1)
return;
Task selectedTask = App.ViewModel.AllTasks[TasksListBox.SelectedIndex];
TasksListBox.SelectedIndex = -1;
NavigationService.Navigate(new Uri("/Views/TaskDetailsPage.xaml?taskId=" + selectedTask.Id, UriKind.Relative));
}
Please Help Me.
Set your ListBox IsSynchronizedWithCurrentItem="False".
What really do you want ?
I you do not want the first item being selected when changing filter, you have first to create a private Task object (and/or a SelectedTask property implementing INotifyPropertyChanged).
On the SelectionChanged event of your listbox, set the SelectedTask with the current selected Task.
Then, after having applied your filter, bind the SelectedItem property to SelectedTask.

Resources