Access control inside a listbox without triggering selectionChanged event - windows-phone-7

For my listbox in windows phone I added a checkbox for each item with the help of this tutorial (option 2). Before I already had a SelectionChanged event for my listbox. How do I prevent firing the event, when the user just checks the checkbox? The SelectionChanged event should only fire when he hits the textbox in the listbox, but not the checkbox.
Thats my listbox:
<ListBox x:Name="toDoItemsListBox" ItemsSource="{Binding Source={StaticResource cvs}}" Grid.Row="1" Margin="12, 0, 12, 0" Width="440" SelectionChanged="goToNavigation" IsSynchronizedWithCurrentItem="False">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<CheckBox IsChecked="{Binding IsFavorite}" Height="48" Width="48" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked" Style="{StaticResource CheckBoxStyle1}"/>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Shortcut}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}" />
<TextBlock Text="{Binding BuildingName}" TextWrapping="Wrap" Style="{StaticResource PhoneTextSubtleStyle}" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
These are my check events:
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
ListBoxItem checedItem = this.toDoItemsListBox.ItemContainerGenerator.ContainerFromItem((sender as CheckBox).DataContext) as ListBoxItem;
if (checedItem != null)
{
checedItem.IsSelected = true;
}
}
private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
{
ListBoxItem checedItem = this.toDoItemsListBox.ItemContainerGenerator.ContainerFromItem((sender as CheckBox).DataContext) as ListBoxItem;
if (checedItem != null)
{
checedItem.IsSelected = false;
}
}
Also I have to mention that the selectionChanged event raises only when I check the checkbox. Not when I uncheck it.

I made it work without the selection changed event. As alternative I used a tap event:
<StackPanel Orientation="Vertical" Tap="StackPanel_Tap">
<TextBlock Text="{Binding Shortcut}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}" />
<TextBlock Text="{Binding BuildingName}" TextWrapping="Wrap" Style="{StaticResource PhoneTextSubtleStyle}" />
</StackPanel>
and in Code behind I get my listitem with:
private void StackPanel_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
// Save current POI.
Object object = (sender as StackPanel).DataContext as Object;
...}

Related

Getting information from child element of stackpanel within listbox

I know there should be a simple solution to this question but I just cant seem to figure it out here is what my code looks like:
<ListBox HorizontalAlignment="Left"
x:Name="locationsNB"
VerticalAlignment="Top"
Height="563"
Width="455"
SelectionChanged="locationsNB_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
Margin="18,0,0,0"
x:Name="placeDetails">
<Image Source="{Binding icon}"
Height="40"
Width="40"
VerticalAlignment="Top"
Margin="0,10,8,0" />
<StackPanel Width="350">
<TextBlock Text="{Binding name}"
FontSize="35"
Foreground="#399B81"
TextWrapping="Wrap" />
<TextBlock Text="{Binding vicinity}"
FontSize="20"
Foreground="#888888"
TextWrapping="Wrap" />
<TextBlock x:Name="reference"
Text="{Binding reference}"
Visibility="Collapsed" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I want to get the stackpanel->reference text (Text="{Binding reference}") of the selected item I dont know what my C# should look like but any help will be greatly appreciated.
If the ItemsSource of your ListBox is bound to a collection of items then you can use the SelectedItem property of the ListBox
private void locationsNB_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listbox = (ListBox)sender;
var myObject = listbox.SelectedItem as MyCustomObject;
if (myObject == null) return;
// perform your custom logic with this item
}

How to access listboxitem template data when an event of it's item control is fired?

I want to access each listboxitem template control's(image and 4 textblock controls )data when the button is clicked from the following hierarchy.
<ListBox x:Name="lstBoxNearbyPlaces" ItemsSource="{Binding Items}" Grid.Row="2" Margin="0,10,0,0" >
<ListBox.ItemTemplate>
<DataTemplate>
<Button Width="400" Height="150" Name="btnPlace" Click="btnPlace_Click_1">
<Button.Content>
<StackPanel Orientation="Horizontal" >
<Image Name="ImgPlace" Source="{Binding PlaceIconURL}" Width="50" />
<TextBlock Name="lblPlaceLat" Text="{Binding PlaceLatLocation}" Visibility="Collapsed"/>
<TextBlock Name="lblPlaceLng" Text="{Binding PlaceLongLocation}" Visibility="Collapsed"/>
<StackPanel Width="350" >
<TextBlock FontSize="20" Text="{Binding PlaceName}" Name="txtAddress" TextWrapping="Wrap" ></TextBlock>
<TextBlock FontSize="20" Text="{Binding PlaceVicinity}" Name="txtLocation" TextWrapping="Wrap"></TextBlock>
<Line MinHeight="5"></Line>
</StackPanel>
</StackPanel>
</Button.Content>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Is it possible to get or read the data of the every control here when the button click event is fired ?
You can get the binding object in the ListBox_SelectionChanged as the selected item.
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ItemModel model= listBox.SelectedItem as ItemModel ;
}
Or In the Buttonclick event you can get it as
private void Button_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
ItemModel model = button.DataContext as ItemModel;
}
Here model is the object which you have bind to that template.

WP7 listpicker selectionchanged selectedindex return -1

I have i little and simple problem. I think.
I have to Listpickers where the second depends on the selection from the first.
I've thought that i could easily be done with use of selectionchanged on the first Listpicker and then get the selected index.
<toolkit:ListPicker ExpansionMode="FullScreenOnly" Grid.Row="0" Name="customers" FullModeHeader="Kunder" Margin="10,50,10,10" Width="350" HorizontalAlignment="Left" SelectionChanged="customers_SelectionChanged">
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}" Margin="12,0,0,0"></TextBlock>
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
<toolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="16,20,0,20">
<TextBlock Text="{Binding Title}" Margin="16,0,0,0" FontSize="30" FontFamily="{StaticResource PhoneFontFamilyLight}"></TextBlock>
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>
And the code for selectionchanged:
private void customers_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
int selindex = customers.SelectedIndex;
MessageBox.Show("index : " + selindex);
Guid costumerid = customers[selindex].id;
Loadprojects();
}
My problem is that selindex always equals -1 and then i get a out of range exception.
What is the best way to solve this?
private void customers_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
int selindex = customers.SelectedIndex;
if (selindex==-1) return;
MessageBox.Show("index : " + selindex);
Guid costumerid = customers[selindex].id;
Loadprojects();
}

Event handling with LongListSelector and list item with checkbox

I've a LongListSelector with the following item template:
<DataTemplate x:Key="stopItemTemplate">
<Grid Margin="{StaticResource PhoneTouchTargetOverhang}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<CheckBox VerticalAlignment="Top" HorizontalAlignment="Left" IsChecked="{Binding Checked}" Click="AlarmActivationClicked" />
<StackPanel Grid.Column="1" VerticalAlignment="Top">
<TextBlock Text="{Binding Stop.Name}" Style="{StaticResource PhoneTextLargeStyle}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" TextWrapping="Wrap" Margin="12,-12,12,6"/>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Distanz:" Style="{StaticResource PhoneTextSmallStyle}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" Width="120"/>
<TextBlock Text="{Binding Distance, Converter={StaticResource MyStringFormatConverter}, ConverterParameter=:1000:\{0:0.0\} km}" Style="{StaticResource PhoneTextSmallStyle}" FontFamily="{StaticResource PhoneFontFamilySemiBold}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Alarm:" Style="{StaticResource PhoneTextSmallStyle}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" Width="120"/>
<TextBlock Text="{Binding Alarm, Converter={StaticResource MyBooleanStringConverter}}" Style="{StaticResource PhoneTextSmallStyle}" FontFamily="{StaticResource PhoneFontFamilySemiBold}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Vibration:" Style="{StaticResource PhoneTextSmallStyle}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" Width="120"/>
<TextBlock Text="{Binding Vibration, Converter={StaticResource MyBooleanStringConverter}}" Style="{StaticResource PhoneTextSmallStyle}" FontFamily="{StaticResource PhoneFontFamilySemiBold}"/>
</StackPanel>
</StackPanel>
</Grid>
</DataTemplate>
And used as followed:
<controls:PivotItem Header="ziele">
<toolkit:LongListSelector x:Name="alarmList" Background="Transparent" IsFlatList="True"
ItemTemplate="{StaticResource stopItemTemplate}" SelectionChanged="AlarmListSelectionChanged" />
</controls:PivotItem>
The SelectionChanged event:
private void AlarmListSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var guid = ((AlarmItem)alarmList.SelectedItem).Id;
NavigationService.Navigate(new Uri(string.Concat("/AlarmDetailPage.xaml?id=", guid), UriKind.Relative));
}
To change details of an item I've subscribed the SelectionChanged event of the LongListSelector. That works as expected.
But if I tap on the checkbox - at first the clicked event of the checkbox is fired, but I don't recognize which checkbox was clicked (the property longlistselector.SelectedItem is old) and just after the SelectionChanged event has fired and try to navigate to the detail page like is happens if I intend to do that.
How can I separate these to events to avoid firing both? And how can I get the corresponding data item?
Thanks a lot...
Kind regards, Danny
You don't need listen to SelectionChanged event. In Click, Checked or Unchecked event handler you can get an item:
private void CheckBox_Checked(object sender, System.Windows.RoutedEventArgs e)
{
var guid = ((sender as CheckBox).DataContext as AlarmItem).Id;
NavigationService.Navigate(new Uri(string.Concat("/AlarmDetailPage.xaml?id=", guid), UriKind.Relative));
}
In your AlarmActivationClicked (event handler on the checkbox) you'll be able to get the dataitem of the item in the list that was click.
private void AlarmActivationClicked(object sender, RoutedEventArgs e)
{
var dataItem = ((FrameworkElement)sender).DataContext;
}
I am not seeing the event AlarmListSelectionChanged method being called after the AlarmActivationClicked method is called. If you click on the checkbox, the checkbox changes to checked, but it doesnt change the selection in the list box.

Reloading listbox in WP7

I am using List to bind a listbox which is as follows:
<ListBox x:Name="ContentPanel" SelectionChanged="onSelectionChanged" Background="LightGray" Grid.Row="2">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Name="{Binding title}" Height="165" Margin="25,5,25,0" Width="430">
<Border BorderThickness="1" Height="165" BorderBrush="Gray">
<toolkit:ContextMenuService.ContextMenu >
<toolkit:ContextMenu IsZoomEnabled="False">
<toolkit:MenuItem Name="Delete" Header="Delete Message" Click="DeleteMessage_Click" >
</toolkit:MenuItem>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<StackPanel Orientation="Vertical">
<StackPanel>
<TextBlock Text="{Binding title}" Margin="5,0,0,0" FontSize="25" Foreground="Black"/>
<TextBlock Text="{Binding msgFrom}" Padding="5" TextWrapping="Wrap" Foreground="Gray" FontSize="20"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="5,13,0,0" FontSize="24" Foreground="WhiteSmoke" Text="{Binding msgReceivedOn}"/>
<toolkit:ToggleSwitch Margin="170,10,0,0" IsChecked="{Binding msgStatus}" Unchecked="UnChecked" Background="LightBlue" Checked="Checked"/>
</StackPanel>
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
At first data is successfully loaded. But when I use the Contextmenu to remove the item and reload the listbox.. it fires an exception. Code to handle the context menu click is:
private void DeleteMessage_Click(object sender, RoutedEventArgs e)
{
MenuItem item = sender as MenuItem;
Message message = (Message)item.DataContext;
MessageBoxResult result = MessageBox.Show("Are you sure to delete the message??", "Confirmation", MessageBoxButton.OKCancel);
if (result == MessageBoxResult.Cancel)
return;
else
{
ContentPanel.Items.Remove(message);
lstMessage.Remove(message);
}
ContentPanel.ItemSource = lstMessage;
}
But it this code is not working. So any suggestions?
You don't need each time to bind collection to a list. Also, when you remove an item from your collection, it should disappear also in the list (if binding setup properly). I think you have not ObservableCollection, so you need manage items manually. Please, consider to use ObservableCollection.
Your code should looks like:
lstMessage.Remove(message); //it must raises CollectionChanged event automatically
And this lines is unnecessary:
ContentPanel.Items.Remove(message);
ContentPanel.ItemSource = lstMessage;

Resources