I am trying to create a listbox containing an Image and some details of it.
Here is the code:
<ListBox x:Name="GalleryImages" ItemsSource="{Binding}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VirtualizingStackPanel.VirtualizationMode="Recycling" Orientation="Vertical" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Disabled" HorizontalAlignment="Center"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid VerticalAlignment="Top">
<Image Source="{Binding Path=ImageSrc}" Height="200" Width="480" Stretch="Fill"/>
<Border BorderThickness="5" BorderBrush="White" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="10" >
<StackPanel HorizontalAlignment="Center" Background="White" Opacity="0.6">
<TextBlock Text="{Binding Path=Time}" Foreground="Black" HorizontalAlignment="Center" Padding="10,5,10,0" FontSize="12" />
<TextBlock Text="{Binding Path=Day}" Foreground="Black" HorizontalAlignment="Center" FontSize="45" FontWeight="Bold" Padding="10,0,10,10" Margin="0,-10,0,-18"/>
<TextBlock Text="{Binding Path=MonthAndYear}" Foreground="Black" HorizontalAlignment="Center" FontSize="17" Padding="10,0,10,5"/>
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
the backened code is:
public class Item
{
public ImageSource ImageSrc { get; set; }
public string Time { get; set; }
public string Day { get; set; }
public string MonthAndYear { get; set; }
}
//Creating a New Item
//Added the time,day, monthandyear
//Now adding the image source
//This will be looped each time for each image
Item item = new Item();
using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication())
{
if (ISF.DirectoryExists("SomeDirectory"))
using (IsolatedStorageFileStream FS = ISF.OpenFile("SomeDirectory/" + "SOMERANDOMIMAGENAME", FileMode.Open, FileAccess.Read))
{
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(FS);
item.ImageSrc = bitmap;
}
}
At last binding the items to the listbox one-by-one created before:
Dispatcher.BeginInvoke(() => GalleryImages.Items.Add(item));
Now the problem is:
As you can see that all the listbox images are being fetched from the Isolated Storage using a new Bitmap Image and then setting it to the item.ImageSrc. But when the items go beyond 25 it creates a Memory Leak and the app crashes after displaying the images
what i tried till now,
added virtualizingstackpanel, which worked but, not for images beyond 25.
set the item.ImageSrc = null just after adding the item to the GalleryImage(ListBox) Items, but that makes the images of the ListBox null too.
What else i can do to work this out, for images more than 1000??
When dealing with collection that contains image, not only UI controls to display the collection that takes considerable amount of memory, but the collection it self too. So, try to look into Data Virtualization in addition to UI Virtualization.
With data virtualization, not all items in the collection loaded to memory at a time. Only portion of it loaded, those needed to be displayed currently plus several next items as buffer.
Related
This is my XAML:
<ListView MouseDoubleClick="ImageList_MouseDoubleClick" Name="ImageList" Background="#353535" Grid.Row="2" Margin="0 5 0 0">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Cursor="Hand" Width="200" Height="130" VerticalAlignment="Center" HorizontalAlignment="Left">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Image Source="{Binding ImgPath}" Grid.Row="0"/>
<Label FontSize="14" Foreground="White" Grid.Row="1" HorizontalAlignment="Center" Content="{Binding Name}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" Width="{Binding Path=ActualWidth, ElementName=ImageList}"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
And this way I add items to ListView:
String[] extensions = { "*.bmp", "*.png", "*.jpg", "*.jpeg", "*.tiff", "*.ico", "*.gif" };
List<String> images = new List<String>();
foreach (String ext in extensions)
{
try
{
images = images.Concat(Directory.GetFiles(path, ext)).ToList();
}
catch { }
}
ObservableCollection<ImageBlock> ImageCollection = new ObservableCollection<ImageBlock>();
foreach (String img in images)
this.ImageList.Items.Add(new ImageBlock(img, System.IO.Path.GetFileName(img)));
This code work perfectly with a little count of images, but when I try to open a folder with more than 100 pictures, my program crashes. What I do wrong or what I can do to optimize my program?
You could have a view model that loads thumbnail image files asynchronously, and also limits their size by setting the DecodePixelWidth or DecodePixelHeight property.
public class ImageData
{
public string Name { get; set; }
public ImageSource ImageSource { get; set; }
}
public class ViewModel
{
public ObservableCollection<ImageData> Images { get; }
= new ObservableCollection<ImageData>();
public async Task LoadFolder(string folderName, string extension = "*.jpg")
{
Images.Clear();
foreach (var path in Directory.EnumerateFiles(folderName, extension))
{
Images.Add(new ImageData
{
Name = Path.GetFileName(path),
ImageSource = await LoadImage(path)
});
}
}
public Task<BitmapImage> LoadImage(string path)
{
return Task.Run(() =>
{
var bitmap = new BitmapImage();
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
bitmap.BeginInit();
bitmap.DecodePixelHeight = 100;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
bitmap.Freeze();
}
return bitmap;
});
}
}
You would bind to such a view model like this:
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
...
<ListBox ItemsSource="{Binding Images}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Width="200" Height="130">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Image Source="{Binding ImageSource}"/>
<TextBlock Grid.Row="1" Text="{Binding Name}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And populate it e.g. in some async input event handler, like:
private async void Button_Click(object sender, RoutedEventArgs e)
{
await ((ViewModel)DataContext).LoadFolder(...);
}
After some long time I found several solutions of this problem. There are easy ways, as for me, and some harder ways.
The easiest way, I think:
In my code in the question we need to change code below:
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" Width="{Binding Path=ActualWidth, ElementName=ImageList}"/>
</ItemsPanelTemplate>
"WrapPanel" replace on "VirtualizingStackPanel". In this way program will work as user #mkArtak suggested:
Also, you should use some kind of virtualization when showing the image thumbnails in the bottom area, as you don't want to load all the images at once. Feels like pretty common scenario to have a control for that available somewhere, which you can reuse. The idea is to load only the images which are visible +2 maybe from each side. Then, load anything else, as the user scrolls.
As I understood this is the virtualization. Of course, you can tune how virtualization must be. You can find info about that in internet.
And a little more harder way: using async\await what suggested user #Clemens
You could have a view model that loads thumbnail image files asynchronously, and also limits their size by setting the DecodePixelWidth or DecodePixelHeight property.
Also, we can use both of this ways and it will be the best way, I think.
Thanks very much everyone for your help in finding the solution of this problem.
I am sharing the screen shot of my application. The image which is coming i want it to be in the side and should be small in size. Here i am not getting the full image also. Can anyone help me to fit the image in the listbox and appear it in the side.
My xaml code is:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox Name="listBox1">
<ListBox.ItemTemplate>
<DataTemplate>
<Button>
<Button.Content>
<ScrollViewer HorizontalScrollBarVisibility="Auto" Height="80" Width="400">
<!--<ScrollViewer Height="80">-->
<StackPanel Orientation="Horizontal" Margin="0,0,0,0">
<StackPanel Orientation="Vertical" Height="80">
<TextBlock Text="{Binding Path=News_Title}" TextWrapping="Wrap" ></TextBlock>
<TextBlock Text="{Binding Path=News_Description}" TextWrapping="Wrap"></TextBlock>
<TextBlock Text="{Binding Path=Date_Start}" TextWrapping="Wrap"></TextBlock>
<Image Source="{Binding ImageBind }" />
</StackPanel>
</StackPanel>
</ScrollViewer>
</Button.Content>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
My .cs code is:
public class Newss
{
public string News_Title { get; set; }
public string News_Description { get; set; }
public string Date_Start { get; set; }
public string image_path { get; set; }
public BitmapImage ImageBind{get;set;}
}
public News()
{
InitializeComponent();
KejriwalService.aapSoapClient client = new KejriwalService.aapSoapClient();
client.getarvindNewsCompleted += new EventHandler<KejriwalService.getarvindNewsCompletedEventArgs>(client_getarvindNewsCompleted);
client.getarvindNewsAsync();
}
void client_getarvindNewsCompleted(object sender, KejriwalService.getarvindNewsCompletedEventArgs e)
{
string result = e.Result.ToString();
List<Newss> listData = new List<Newss>();
XDocument doc = XDocument.Parse(result);
foreach (var location in doc.Descendants("UserDetails"))
{
Newss data = new Newss();
data.News_Title = location.Element("News_Title").Value;
//data.News_Description = location.Element("News_Description").Value;
data.Date_Start = location.Element("Date_Start").Value;
data.image_path = location.Element("image_path").Value;
data.ImageBind = new BitmapImage(new Uri( #"http://political-leader.vzons.com/ArvindKejriwal/images/uploaded/"+data.image_path, UriKind.Absolute));
listData.Add(data);
}
listBox1.ItemsSource = listData;
}
Try to move your Image outside inner StackPanel :
.....
<StackPanel Orientation="Horizontal" Margin="0,0,0,0">
<StackPanel Orientation="Vertical" Height="80">
<TextBlock Text="{Binding Path=News_Title}" TextWrapping="Wrap" ></TextBlock>
<TextBlock Text="{Binding Path=News_Description}" TextWrapping="Wrap"></TextBlock>
<TextBlock Text="{Binding Path=Date_Start}" TextWrapping="Wrap"></TextBlock>
</StackPanel>
<Image Source="{Binding ImageBind }" />
</StackPanel>
.....
That will make the Image appear besides the Text. Then try to set Width and Height properties of Image control to fixed value, and set Stretch property appropriately. See this post for reference about setting Stretch property.
There're too many wrong things here, and I don't know what you want.
You've put buttons inside items of ListBox. You should either remove buttons and rely on listbox own items selection mechanism for handling touch elents, or continue using buttons but replace ListBox with ItemsControl that doesn’t handle touch.
You’ve put ScrollViewer inside those buttons. So if you have 10 items, you’ll have 10 buttons, each with its own scroll viewer. Why you did that?
You’ve set height of your StackPanel to 80. When specifying fixed height, Silverlight often does not care whether the content fits or no, instead it clips things. It’s rarely a good idea to specify absolute size of elements.
Instead of using two nested stack panels, you should use single Grid with two rows and two columns, where image occupies both rows of the second column (using Grid.RowSpan property).
And you’re asking question about changing image style? You should fix the rest of your XAML first…
so i am working on a Windows Phone 7 application, and i am having a problem, normally in my other WPF/WinForm applications this code would work but here on Wphone 7 i am receiving a problems, i created data class:
public class AlarmTemplate
{
public string Name { get; set; }
public string Time { get; set; }
public BitmapImage Activated { get; set; }
public AlarmTemplate(string name, string time, string activated)
{
Name = name;
Time = time;
Activated = new BitmapImage
{UriSource = new Uri("Images/alarm_" + activated + ".png", UriKind.RelativeOrAbsolute)};
}
}
Next thing read dad, also i tried with hard coding data and its not working:
private List<AlarmTemplate> _templateList = new List<AlarmTemplate>();
private void PopulateList()
{
using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!storage.FileExists("file.txt"))
return;
using (var reader = new BinaryReader(storage.OpenFile("file.txt", FileMode.Open)))
{
var s = reader.ReadInt32();
for (var i = 0; i < s; i++)
{
_templateList.Add(new AlarmTemplate(reader.ReadString(), reader.ReadString(),
reader.ReadString()));
}
}
}
lbAlarms.ItemsSource = _templateList;
}
Here is xaml:
<ListBox Height="176.135" HorizontalAlignment="Left" Margin="0,567.164,0,0" Name="lbAlarms" VerticalAlignment="Top" Width="456" Foreground="#FFFFC7C7" ItemsSource="{Binding}" Background="Transparent" AllowDrop="False" BorderThickness="1" BorderBrush="#00900707" Grid.Row="1" Hold="lbAlarms_Hold">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Grid.Row="1" Height="52" Orientation="Horizontal" Name="spList" VerticalAlignment="Top" Width="480" Margin="0,329,0,0" UseLayoutRounding="False">
<Image Height="52" Name="imTStatus" Stretch="Uniform" Width="73" Margin="10,0,0,0" UseLayoutRounding="False" Source="{Binding Activated}" />
<StackPanel Height="52" Name="spHolder" Width="300" Margin="10,0,0,0" VerticalAlignment="Stretch" HorizontalAlignment="Left" UseLayoutRounding="False">
<TextBlock Height="26" Name="tbTTime" Text="{Binding Time}" Foreground="Black" FontFamily=".\Fonts\Nokia.ttf#Nokia" TextAlignment="Left" FontWeight="Bold" Width="230" FontSize="24" HorizontalAlignment="Left" UseLayoutRounding="False" />
<TextBlock Height="26" Name="tbTName" Text="{Binding Name}" Foreground="Black" FontFamily=".\Fonts\Nokia.ttf#Nokia" HorizontalAlignment="Left" Width="297" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Your code is working (I noticed the scrollbar was present on the right), but your text colour is black on black so not very visible.
Get rid of the TextBlock colour Foreground="Black" :)
Note, your margin means your listbox is very small at the bottom of the page, less than 1 item high, so you might want to change that as well.
private List<AlarmTemplate> _templateList = new List<AlarmTemplate>();
public List<AlarmTemplate> TemplateList
{
get { return _templateList; }
set { _templateList = value; }
}
and set the binding to TemplateList.
PROBLEM:
I got the answer when doing some binding from ListBoxSource to ListBoxDisplay BUT weird thing happened:
The selecting and deselecting of items are working fine and displays exactly the selected items on the other ListBox named "ListBoxDetails BUT everytime I select an item the image is gone but selection highlights remain but has no more image in it. (You can still deselect it though even if no more image because the screenspace is still there)
NOTE: I have no other control inside the ListBoxSource (SelectionMode=Multiple) ONLY Image
CODE XAML:
<Window.Resources>
<DataTemplate x:Key="ItemTemplate">
<WrapPanel Height="149" Orientation="Horizontal" Width="193">
<Image HorizontalAlignment="Left" Height="128" Width="180" Margin="0"/>
</WrapPanel>
</DataTemplate>
<ItemsPanelTemplate x:Key="ItemsPanelTemplate1">
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
<ItemsPanelTemplate x:Key="ItemsPanelTemplate2">
<UniformGrid x:Name="UniformGridImageList"/>
</ItemsPanelTemplate>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<ListBox x:Name="ListBoxSource" Width="450" Margin="9,3,442,178" ItemsPanel="{DynamicResource ItemsPanelTemplate2}" SelectionMode="Multiple" d:LayoutOverrides="GridBox" HorizontalAlignment="Left" />
<ListBox Name="ListBoxDisplay" Height="659" HorizontalAlignment="Right" Margin="460,5,0,0" VerticalAlignment="Top" Width="382" ItemsSource="{Binding ElementName=ListBoxSource, Path=SelectedItems}" />
<Button x:Name="buttonLoadImages" Content="Button" HorizontalAlignment="Left" Height="51" Margin="33,0,0,70" VerticalAlignment="Bottom" Width="183" Style="{DynamicResource ButtonStyle1}" Click="buttonLoadImages_Click"/>
<Button Content="Clear" Height="55" HorizontalAlignment="Right" Margin="0,717,442,0" Name="buttonClearListBox" VerticalAlignment="Top" Width="177" Click="button1_Click" />
</Grid>
CODE C#:
above declaration:
private List<Image> _imageList = new List<Image>();
.
.
.
private void buttonLoadImages_Click(object sender, System.Windows.RoutedEventArgs e)
{
this._imageList = GetImageList(#"C:\Users\Public\Pictures\Sample Pictures");
foreach (Image curImage in this._imageList)
{
ListBoxSource.Items.Add(curImage);
}
}
#region GetImageList Method
private List<Image> GetImageList(string strPath)
{
List<Image> imageList = new List<Image>();
string strFilePath = "";
if (Directory.Exists(strPath) == false)
{
MessageBox.Show(string.Format("{0} path could not be found.", strPath));
return imageList;
}
try
{
DirectoryInfo dirInfo = new DirectoryInfo(strPath);
FileInfo[] files = dirInfo.GetFiles("*.jpg",SearchOption.AllDirectories);
foreach (FileInfo curFile in files)
{
strFilePath = curFile.FullName;
Image curImage = new Image();
BitmapImage bmpImage = new BitmapImage();
bmpImage.BeginInit();
bmpImage.UriSource = new Uri(curFile.FullName, UriKind.Absolute);
bmpImage.EndInit();
curImage.Height = 140;
curImage.Stretch = Stretch.Fill;
curImage.Source = bmpImage;
curImage.Margin = new Thickness(10);
imageList.Add(curImage);
}
if (imageList.Count == 0)
MessageBox.Show(string.Format("No image files could be found in {0}", strPath));
}
catch (Exception ex)
{
MessageBox.Show(string.Format("{0}-{1}", ex.Message, strFilePath));
}
return imageList;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
this.listBoxSource.Items.Clear();
}
You are creating Image UI objects and adding them directly to your ListBox.
This means that the SelectedItems is an Image UI object, so ListBox #2 is trying to set it's Items to the exact same Image object reference. This isn't allowed in WPF because UI objects can only have a single parent, however because it is a Binding error, WPF is silent about it (except for probably a warning)
I would recommend making your List<Image> into a List<string> which contains the path name for the image, and changing your <Image> in the template to use that string as it's Source. Also, don't forget to set the ItemTemplate on both your ListBoxes.
<DataTemplate x:Key="ItemTemplate">
<WrapPanel Height="149" Orientation="Horizontal" Width="193">
<Image Source="{Binding }" HorizontalAlignment="Left" Height="128" Width="180" Margin="0" />
</WrapPanel>
</DataTemplate>
I did a quick test and it works fine once you fill your ListBoxes with Strings instead of UI objects
What I am trying to do is to create some sort of "rooms"(like a chat group, a sharing center or whatever you want). All the room are created the same way, but each one of them contains different informations. Each of these rooms is contained in a TabItem. I managed to create dynamically all the Tabitems, to give those a Grid and a Canvas. But at the moment I am facing a problem: I created a ControlTemplate Called RoomMenu that will show different buttons and, the most important, the people connected in this room in a ListBox(I retrieve those people from a WebService each time I change the selected Tabitem). But since my ListBox is in a ControlTemplate I have no idea how to access the ListBox ItemSource to bind a generic List to it. Down Below is the code used to create my rooms and their content.
Here is my room menu class:
public class RoomMenu : ContentControl
{
public RoomMenu()
{
DefaultStyleKey = typeof(RoomMenu);
}
public string Current_room_id;
public string FullName;
public string Rights;
}
And here is the ControlTemplate located in generic.xaml:
<Style TargetType="test:RoomMenu">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="test:RoomMenu">
<Grid x:Name="MenuGrid">
<Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="Black" CornerRadius="2" Background="Black">
<StackPanel Orientation="Vertical">
<Border x:Name="Room_friend_border" Background="Gray" CornerRadius="4" Margin="5">
<ListBox x:Name="current_room_friends" ItemsSource="{Binding ''}" Margin="5" Height="230">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FullName}" Height="20"/>
<TextBlock Text="{Binding Rights}" Height="20"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
<Border x:Name="Room_menu" Background="Gray" CornerRadius="4" Margin="5">
<StackPanel Orientation="Vertical" Margin="10">
<Button Content="Add item" Margin="0,2,0,2"/>
<Button Content="Set changes" Margin="0,2,0,2"/>
<Button Content="Invite friend" Margin="0,2,0,2"/>
<Button Content="Rename room" Margin="0,2,0,2"/>
<Button Content="Delete room" Margin="0,2,0,2"/>
</StackPanel>
</Border>
</StackPanel>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Here is my Dictionnary Class that contains the RoomMenu:
public class Rooms : TabItem
{
public string Room_guid;
public string Room_name;
public string Primary_user_guid;
public string Room_version;
public Grid Room_grid;
public Canvas Room_canvas;
public RoomMenu Room_menu;
}
And this is when I call my ControlTemplate and Add it to my TabItem's Grid:
public void Set_rooms_interface()
{
foreach (KeyValuePair<string, Rooms> kvp in rooms_list)
{
rooms_list[kvp.Key].Room_menu = new RoomMenu();
rooms_list[kvp.Key].Room_canvas = new Canvas();
rooms_list[kvp.Key].Room_grid = new Grid();
//instance grid columns
rooms_list[kvp.Key].Room_grid.ColumnDefinitions.Add(new ColumnDefinition() {Width = new GridLength(900)});
rooms_list[kvp.Key].Room_grid.ColumnDefinitions.Add(new ColumnDefinition());
//Refreshing room canvas
rooms_list[kvp.Key].Room_canvas.Height = rooms_list[kvp.Key].Room_grid.ActualHeight;
rooms_list[kvp.Key].Room_canvas.Width = rooms_list[kvp.Key].Room_grid.ActualWidth;
rooms_list[kvp.Key].Room_canvas = refresh_canvas(kvp.Key);
Grid.SetColumn(rooms_list[kvp.Key].Room_canvas, 0);
Grid.SetColumn(rooms_list[kvp.Key].Room_menu, 1);
//Add Canvas to Grid
rooms_list[kvp.Key].Room_grid.Children.Add(rooms_list[kvp.Key].Room_canvas);
rooms_list[kvp.Key].Room_grid.Children.Add(rooms_list[kvp.Key].Room_menu);
//Setting TabItem Name
rooms_list[kvp.Key].Header = rooms_list[kvp.Key].Room_name;
//Adding Grid to TabItem.Content
rooms_list[kvp.Key].Content = rooms_list[kvp.Key].Room_grid;
//Adding TabItem to TabControl
Room_tab.Items.Add(kvp.Value);
}
}
I'm sorry if the whole question is a bit long but it was the only way to explain clearly what I was trying to do. So if anyone could give me a hint or answer to do some databinding in a ControlTemplate it would greatly help me.
Thank You.
I think you started in the wrong direction when instantiating UI elements in code. The code behind should only contain one line assigning the people list to the current_room_friends DataContext.
Start with simpler examples of binding data to a ListBox like the beautiful planet example of Bea Stollnitz.