get items in listboxitem - windows-phone-7

I have an xaml code about listbox object:
<ListBox x:Name="FirstListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="FirstListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Grid>
<TextBlock Text="{Binding LineOne}" TextWrapping="NoWrap" Margin="50,0,0,0" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding LineTwo}" TextWrapping="NoWrap" Margin="12,60,0,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
<CheckBox VerticalAlignment="Top" Margin="0,-5,0,0"/>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
i was get my listboxitem by the code :
ListBoxItem item = this.list.ItemContainerGenerator.ContainerFromIndex(2) as ListBoxItem;
but i don't know how to get all items in this listbox item (including textblock and checkbox option).
please help me. thanks all.

Ideally, you'd want to have your checkbox bound to a property of your item data model, so for example, you may have...
public string LineOne { get; set; }
public string LineTwo { get; set; }
public bool MyBooleanValue { get; set; }
and then
<ListBox x:Name="FirstListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="FirstListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Grid>
<TextBlock Text="{Binding LineOne}" TextWrapping="NoWrap" Margin="50,0,0,0" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding LineTwo}" TextWrapping="NoWrap" Margin="12,60,0,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
<CheckBox Checked="{Binding MyBoolValue, Mode=TwoWay}" VerticalAlignment="Top" Margin="0,-5,0,0"/>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Then you can pull back the DataContext for the item you are currently looking at (on a tap method or similar), or when you parse through your "Items" collection, all the checkbox states will be in the child objects for you already.

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
}

Binding in Nested List Boxes to multiple classes

I'm making a nested listed box , basically because I need to bind multiple classes in a single list box , which I'm not able to do and hence the nested listed box.
Here's what I do in the XAML page :
<ListBox Name="abcd" Margin="10,0,30,0" ItemsSource="{Binding Title}" SelectionChanged="ListBox_SelectionChanged" Height="486" Width="404" FontSize="20">
<ListBox.ItemTemplate>
<DataTemplate >
<StackPanel Margin="0,0,10,0" Width="380" Height="140">
<Grid >
<TextBlock Text="{Binding cdata}" TextWrapping="Wrap" FontSize="{StaticResource PhoneFontSizeLarge}" />
<ListBox Name="ab" ItemsSource="{Binding Description}" FontSize="14">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Width="380" Height="100">
<Grid>
<TextBlock Text="{Binding cdata}" TextWrapping="Wrap" FontSize="{StaticResource PhoneFontSizeLarge}" />
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
where ListBox "abcd" has to be bound with class title and "ab" to the class Description.Both the classes have just one string field , "cdata".
In the xaml.cs I do :
abcd.ItemsSource=from article in root.openfooty.news.article
select new Classes.Title
{
cdata = article.title.cdata
};
ab.ItemSource = from article in root.openfooty.news.article
select new Classes.Description
{
cdata = article.description.cdata
};
binding with "abcd" works fine but with "ab" it says "the nam ab doesnt exist in the current context"
Any help would be much appreciated. Thanks :D
Why don't you write a single class like this
public class TitleDescription
{
public string title { get; set; }
public string description { get; set; }
}
and try the databinding ?
abcd.ItemsSource=from article in root.openfooty.news.article
select new Classes.TitleDescription
{
title = article.title.cdata,
description = article.description.cdata
};
And have only one list box like this
<ListBox Name="abcd" Margin="10,0,30,0" SelectionChanged="ListBox_SelectionChanged" Height="486" Width="404" FontSize="20">
<ListBox.ItemTemplate>
<DataTemplate >
<StackPanel Margin="0,0,10,0" Width="380" Height="140">
<Grid >
<TextBlock Text="{Binding description}" TextWrapping="Wrap" FontSize="{StaticResource PhoneFontSizeLarge}" />
<TextBlock Text="{Binding title}" TextWrapping="Wrap" FontSize="{StaticResource PhoneFontSizeLarge}" />
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

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;

WP7 Tombstoning - Easy practice

I have a databound xml reader. MainPage is connected to DetailsPage: When user clicks on the name in Main Page, She gets the details of this name (Age, Gender, Date of Birth etc.) in the DetailsPage.
I am in trouble with tombstoning atm. When I click on windows button, then click on back button I get into an empty DetailsPage.
What would be the easiest way to solve this problem? I tried to use TombstoneHelper but it also shows empty page.
DetailsPage.xaml
<controls:PanoramaItem Header="" Margin="0,0,0,80">
<ScrollViewer>
<StackPanel>
<TextBlock TextWrapping="Wrap" Width="432" Style="{StaticResource PhoneTextExtraLargeStyle}" Margin="0,0,0,10" d:LayoutOverrides="Width" Foreground="#DEFFFFFF"><Run Text="Personal D"/><Run Text="e"/><Run Text="tails"/></TextBlock>
<StackPanel HorizontalAlignment="Left" Width="432" Orientation="Horizontal">
<TextBlock TextWrapping="Wrap" Margin="20,0,7,0" Foreground="#DEFFFFFF"><Run Text="Name"/><Run Text=":"/></TextBlock>
<TextBlock x:Name="username" TextWrapping="Wrap" Text="{Binding Name}" Foreground="#DEFFFFFF" />
</StackPanel>
<StackPanel HorizontalAlignment="Left" Width="432" Orientation="Horizontal">
<TextBlock TextWrapping="Wrap" Margin="20,0,7,0" Foreground="#DEFFFFFF"><Run Text="Age"/><Run Text=":"/></TextBlock>
<TextBlock x:Name="age" TextWrapping="Wrap" Text="{Binding Age}" Foreground="#DEFFFFFF"/>
</StackPanel>
<StackPanel HorizontalAlignment="Left" Width="432" Orientation="Horizontal">
<TextBlock TextWrapping="Wrap" Margin="20,0,7,0" Foreground="#DEFFFFFF"><Run Text="Nationality"/><Run Text=":"/></TextBlock>
<TextBlock x:Name="country" TextWrapping="Wrap" Text="{Binding Country}" Foreground="#DEFFFFFF"/>
</StackPanel>
<StackPanel HorizontalAlignment="Left" Width="432" Orientation="Horizontal">
<TextBlock TextWrapping="Wrap" Margin="20,0,7,0" Foreground="#DEFFFFFF"><Run Text="Country of Birth"/><Run Text=":"/></TextBlock>
<TextBlock x:Name="cobirth" TextWrapping="Wrap" Text="{Binding Cobirth}" Foreground="#DEFFFFFF"/>
</StackPanel>
<StackPanel HorizontalAlignment="Left" Width="432" Orientation="Horizontal">
<TextBlock TextWrapping="Wrap" Margin="20,0,7,0" Foreground="#DEFFFFFF"><Run Text="Place of Birth"/><Run Text=":"/></TextBlock>
<TextBlock x:Name="fobirth" TextWrapping="Wrap" Text="{Binding Pobirth}" Foreground="#DEFFFFFF"/>
</StackPanel>
</StackPanel>
</ScrollViewer>
</controls:PanoramaItem>
DetailsPage.cs
using TombstoneHelper;
public User()
{
InitializeComponent();
SupportedOrientations = SupportedPageOrientation.Portrait;
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
this.SaveState(); // <- first line
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
this.RestoreState(); // <- second line
}
Mainpage.Cs
private void UserListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0)
{
NavigationService.Navigate(new Uri("/DetailsPage.xaml", UriKind.Relative));
FrameworkElement root = Application.Current.RootVisual as FrameworkElement;
root.DataContext = (RosterItem)e.AddedItems[0];
((ListBox)sender).SelectedIndex = -1;
}
}
All things being equal Tombstone helper should just work. Remember that you need to have named your controls (with an x:Name attribute) for Tombstone helper to access them. Also make sure you are calling SaveState() in your NavigatedFrom() method and RestoreState() in NavigatedTo() (and not the other way round).
If that doesn't something must be wrong elsewhere in your code. We might be able to help if you post the relevant parts of your code.

WP7 image binding

I have a Windows phone 7 application which contains a listbox. I want, for each item in the listbox to have a particular image.
<ListBox Height="606" HorizontalAlignment="Left" ScrollViewer.VerticalScrollBarVisibility="Visible"
Margin="20,20,0,0"
Name="listBox1" VerticalAlignment="Top" Width="414" ItemsSource="{Binding SubList, Mode=OneWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Height="50" Width="50"
VerticalAlignment="Top" Margin="0,10,8,0" Source="{Binding Image, Mode = OneWay}"/>
<StackPanel Orientation="Vertical">
<HyperlinkButton Content="{Binding Cathegory, Mode=OneWay}" NavigateUri="" HorizontalAlignment="Right">
</HyperlinkButton>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And the property binded to the Source property of the Image control is an Uri.
My problem is that the image is not shown in the listbox.
I have tried using a string instead of the Uri but I get the same issue.
I kindly appreciate any help :).
This should work:
public class Item
{
public int Number { get; set; }
public Uri ImageUri { get; set; }
public Item(int number, Uri imageUri)
{
Number = number;
ImageUri = imageUri;
}
}
And the datatemplate:
<ListBox x:Name="Items">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Number}"></TextBlock>
<Image Source="{Binding ImageUri}"></Image>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Check out this other SO answer, I believe it contains the answer to your question:
Image UriSource and Data Binding
But the basics of it is that you need to convert your URI/string to a BitmapImage (either via viewmodel property, or converter)

Resources