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)
Related
I have this xaml
<ListBox x:Name="listBox"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
Tap="listBox_Tap">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<Image Name="cPix"
Source="{Binding Image}"
Stretch="None"
Margin="0,0,5,5"
ToolTipService.Placement="Bottom"
ToolTipService.ToolTip="{Binding Name}" />
<TextBlock Text="{Binding Name}"
HorizontalAlignment="Center"
Foreground="Black" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
the concept is that, i want the listbox to lazy load images, there will be a placeholder image first, and while the images finish downloading, the placeholder give way to the downloaded image.
Any help?
You can solve this in your ViewModel. Here is an example pseudo code:
public BitmapImage Image
{
get
{
if (_image == null)
ImageManager.LoadImageAsync(_imageUri).ContinueWith(t=> Image = t.Result);
return _image;
}
set
{
_image = value;
NotifyPropertyChanged("Image");
}
}
Your ImageManager would load images asynchronously, whether from cache, IsolatedStorage or web and when done, it would complete the internal Task.
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>
I'm trying to present a listview in wp7 and for some reason it doesn't seem to work
my xaml
<!--ContentPanel - place additional content here-->
<StackPanel x:Name="ContentPanel2" Grid.Row="1" Margin="12,0,12,0">
<ListBox x:Name="list">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="5">
<Image Source="{Binding ImageUri}" Stretch="None"/>
<TextBlock Text="{Binding Text}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Grid>
my c# code
public class list
{
public string title { get; set; }
public string imageSource { get; set; }
}
and
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
List<list> dataSources = new List<list>();
dataSources.Add(new list() { title = "Shacharit", imageSource = "Images/shacharit.png" });
dataSources.Add(new list() { title = "Mincha", imageSource = "Images/mincha.png" });
dataSources.Add(new list() { title = "Arvit", imageSource = "Images/arvit.png" });
dataSources.Add(new list() { title = "Birkat HaMazon", imageSource = "Images/shacharit.png" });
list.ItemsSource = dataSources;
}
Thanks in advance
Try the below, change the bindings of image and text block to bind to the strings you have declared at present you are trying to bind to ImageURI and Text and they don't exist in any of your code.
<!--ContentPanel - place additional content here-->
<StackPanel x:Name="ContentPanel2" Grid.Row="1" Margin="12,0,12,0">
<ListBox x:Name="list" Da>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="5">
<Image Source="{Binding imageSource }" Stretch="None"/>
<TextBlock Text="{Binding title}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Grid>
To Clarify Jon D's answer, you are creating data objects with attributes of "imagePath" and "title" in your code behind
new list() { title = "Shacharit", imageSource = "Images/shacharit.png" };
but trying to bing to properties called "ImageUri" and "Text".
In your output window in VS you should see these binding errors show up.
The following 2 lines (where you are doinng the binding in the XAML) should fix things up for you...
<Image Source="{Binding imageSource }" Stretch="None"/>
<TextBlock Text="{Binding title}"/>
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.
How can I bind all the artists from the Artists collection to a ListBox in a PanoramaItem?
My xaml is as follows:
<controls:PanoramaItem Header="Artist" Name="Pan3">
<!--Double line list with image placeholder and text wrapping-->
<ListBox Name="artistLb" Margin="0,0,-12,0" ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0,0,0,17">
<!--Replace rectangle with image-->
<Rectangle Height="100" Width="100" Fill="#FFE5001b" Margin="12,0,9,0"/>
<StackPanel Width="311">
<TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PanoramaItem>
and xaml.cs code:
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
MediaLibrary library = new MediaLibrary();
int CountArtist = library.Artists.Count;
//binding the library.Artist to the Panorama item
}
Thanks!
In my answer I will assume you started from a Windows Phone Panorama Project and already added the reference to Microsoft.Xna.Framework to gain access to the media library.
When binding Ui object like the ListBox to code behind the best solution is to stick with the ViewModel approach that is already provided in the project. In your project you should find a MainViewModel. To this viewmodel add the following property:
private MediaLibrary _library;
public MediaLibrary Library
{
get
{
if (_library == null)
{
_library = new MediaLibrary();
}
return _library;
}
}
This property exposes the MediaLibrary to your xaml. The library is instantiated when called for the first time.
From your xaml it is now possible to bind to this property, I am only showing the ListBox.
<ListBox Margin="0,0,-12,0" ItemsSource="{Binding Library.Artists}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Height="78">
<TextBlock Text="{Binding Name}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Notice that I am binding the ListBox to the subproperty Artists of the Library property we just created in the viewmodel. I edited the ItemTemplate to show just one TextBlock that binds to the Artist name.
On your emulator you will just see 1 artist as an example, to test this solution with a real device you will have to use the WPConnect tool, which is explained here
I hope this gets you going for now, please let me know if any questions remain.
Have you tried?
artistLb.DataContext = library.Artists;