WPF, C# - Observable Collection Problem Displaying an ItemTemplate in WPF Listbox

cardinalone
cardinalone used Ask the Experts™
on
Using WPF, C# - binding an object to a WPF ListBox with a DataTemplate.

The goal is to declaratively bind an ObservableCollection class to a WPF ListBox. The LIstBox should display a collection of Images (PNG Files). The ObservableCollection class picks up image files via a FileWatcher and has a FUlLPath public property that is used to bind the SOURCE property of an IMAGE element.

However, the ListBox will not render the images. WHen I debug, the ObservableCollection class DOES populate with items, and I can access the FullPath property.

I found out via MSDN that to make my ObservableCOllection class get recognized in XAML, I had to add a namesspace in my Widnow declaration.
 
   xmlns:src="clr-namespace:Wpf_SomethingFishy"

and also a Resource for the class.

    <Window.Resources>
        <src:FishBooks x:Key="FishBooks"/>
...

because prior the ListBox
<ListBox ItemsSource="{Binding Source={StaticResource FishBooks}}

was getting a compile error :FishBooks...not found..."

But I still am not able to get the ListBox to render the class Collection items.

All COde is pasted below.

App.XAML
<Application x:Class="Wpf_SomethingFishy.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Window1.xaml">
</Application>
 
APP.XAML CODE BEHIND
using System;
using System.ComponentModel;
using System.IO;
using System.IO.IsolatedStorage;
using System.Threading;
using System.Windows;
using System.Windows.Data;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
 
 
namespace Wpf_SomethingFishy
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
 
        }
    }
}
 
 
 
FISHBOOK CLAss
using System;
using System.IO;
 
namespace Wpf_SomethingFishy
{
    public class FishBook
    {
        string name;
        DateTime dateTime;
        string size;
        string path;
 
        public FishBook(string filename)
        {
            FileInfo info = new FileInfo(filename);
            size = (info.Length / 1024).ToString("N0") + " KB";
            dateTime = info.LastWriteTime;
            name = info.Name;
            path = info.DirectoryName;
        }
 
        public string Name
        {
            get { return name; }
        }
 
        public DateTime DateTime
        {
            get { return dateTime; }
        }
 
        public string Size
        {
            get { return size; }
        }
 
        public string Path
        {
            get { return path; }
        }
 
        public string FullPath
        {
            get { return System.IO.Path.Combine(Path, Name); }
        }
 
        public override string ToString()
        {
            return FullPath;
        }
    }
}
 
 
FISHBOOKS Class
using System;
using System.IO;
using System.Collections.Generic;
using System.Collections.ObjectModel;
 
namespace Wpf_SomethingFishy
{
    public class FishBooks : ObservableCollection<FishBook>
    {
        Dictionary<string, FileSystemWatcher> watchers = new Dictionary<string, FileSystemWatcher>();
 
        public event EventHandler ItemsUpdated;
 
        protected override void ClearItems()
        {
            base.ClearItems();
            watchers.Clear();
        }
 
        protected override void InsertItem(int index, FishBook item)
        {
            base.InsertItem(index, item);
            if (!watchers.ContainsKey(item.Path))
            {
                FileSystemWatcher watcher = new FileSystemWatcher(item.Path, "*.png");
                watcher.EnableRaisingEvents = true;
                watcher.Created += new System.IO.FileSystemEventHandler(OnPhotoCreated);
                watcher.Deleted += new System.IO.FileSystemEventHandler(OnPhotoDeleted);
                watchers.Add(item.Path, watcher);
            }
        }
 
 
        void OnPhotoDeleted(object sender, System.IO.FileSystemEventArgs e)
        {
            int index = -1;
            for (int i = 0; i < Items.Count; i++)
            {
                if (Items[i].FullPath == e.FullPath)
                {
                    index = i;
                    break;
                }
            }
            if (index >= 0)
                Items.RemoveAt(index);
 
            if (ItemsUpdated != null)
                ItemsUpdated(this, new EventArgs());
        }
 
        void OnPhotoCreated(object sender, System.IO.FileSystemEventArgs e)
        {
            Items.Add(new FishBook(e.FullPath));
 
            if (ItemsUpdated != null)
                ItemsUpdated(this, new EventArgs());
        }
    }
}
 
 
FISH CONTROLLER CLass
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.IO;
using System.Threading;
using System.Windows.Threading;
 
namespace Wpf_SomethingFishy
{
    public class FishController
    {
        public FishController()
        {
              FishBooks fishbks = new FishBooks();
 
            foreach (string s in Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures).ToString() + System.IO.Path.DirectorySeparatorChar + "Fish", "*.png"))
                {
//               fishbks.ItemsUpdated += delegate { this.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadStart(Refresh)); };
                 FishBook fish = new FishBook(s);
                 fishbks.Add(fish);
                }
        }
 
 
    }
}
 
 
WINDOW1.XAML
 
<Window x:Class="Wpf_SomethingFishy.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:src="clr-namespace:Wpf_SomethingFishy"
    Title="Under the Sea" Height="750" Width="590" WindowStyle="SingleBorderWindow" Background="Transparent">
    <Window.Resources>
        <src:FishBooks x:Key="FishBooks"/>
        <LinearGradientBrush x:Key="ButtonBrushOrange" StartPoint="0,0" EndPoint="0,1">
            <GradientStop Offset="0.45" Color="Orange" />
            <GradientStop Offset="0.45" Color="Orange" />
            <GradientStop Offset="0.6" Color="DarkOrange" />
            <GradientStop Offset="0.9" Color="DarkOrange" />
        </LinearGradientBrush>
        <LinearGradientBrush x:Key="ButtonBrushBlack" StartPoint="0,0" EndPoint="0,1">
            <GradientStop Offset="0.45" Color="DarkSlateGray"  />
            <GradientStop Offset="0.45" Color="DarkSlateGray" />
            <GradientStop Offset="0.6" Color="Black" />
            <GradientStop Offset="0.9" Color="Black" />
        </LinearGradientBrush>
        <ControlTemplate x:Key="buttonControlTemplate">
            <Grid Width="150" Height="Auto" >
                <Ellipse x:Name="Disc" Width="125" Height="125" Fill="{StaticResource ButtonBrushBlack}"></Ellipse>
                <Viewbox>
                    <ContentPresenter Margin="1" Content="{TemplateBinding Button.Content}"/>
                </Viewbox>
            </Grid>
        </ControlTemplate>
        <HierarchicalDataTemplate DataType="NavItems" ItemsSource="{Binding XPath=*}">
            <StackPanel Orientation="Horizontal">
                <Image Source="Fish\shiirafish.png" Height="42" Width="42" Margin="0,0,5,0"/>
                <TextBlock Foreground="White" FontStyle="Normal" FontFamily="Calibri" FontSize="12" Text="{Binding XPath=@Header}"/>
            </StackPanel>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="NavItem" ItemsSource="{Binding XPath=*}">
            <StackPanel Orientation="Horizontal">
                <Image Source="Fish\babelfish.png" Height="42" Width="42" Margin="0,0,5,0"/>
                <TextBlock Foreground="White" FontStyle="Normal" FontFamily="Calibri" FontSize="12" Text="{Binding XPath=@Type}"/>
            </StackPanel>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="NavItem1" ItemsSource="{Binding XPath=*}">
            <StackPanel Orientation="Horizontal">
                <Image Source="Fish\redFish.png" Height="42" Width="42" Margin="0,0,5,0"/>
                <TextBlock Foreground="White" FontStyle="Normal" FontFamily="Calibri" FontSize="12" Text="{Binding XPath=@SubType}"/>
            </StackPanel>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="Fish" ItemsSource="{Binding XPath=*}">
            <StackPanel Orientation="Horizontal">
                <Image Source="Fish\fish-1.png" Height="42" Width="42" Margin="0,0,5,0"/>
                <TextBlock Foreground="White" FontStyle="Normal" FontFamily="Calibri" FontSize="12" Text="{Binding XPath=Fish}"/>
            </StackPanel>
        </HierarchicalDataTemplate>
        <XmlDataProvider x:Key="BlueDataProvider" XPath="NavItems" Source="BlueNavItems.xml" />
        <Style TargetType="TreeViewItem">
            <Setter Property="IsExpanded" Value="True" />
        </Style>
    </Window.Resources>
    
    <Grid Background="{StaticResource ButtonBrushOrange}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="220"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" VerticalAlignment="Top" Height="155">
        <WrapPanel  HorizontalAlignment="Left" Grid.Column="0" >
        <Button Template="{StaticResource buttonControlTemplate}" Click="btnGo_Click" >
            <Image Source="Fish\diver.png" Height="9" Width="9" />
        </Button>
        </WrapPanel>
        </StackPanel>
        <StackPanel Margin="0,161,0,0" Grid.RowSpan="2">
            <TreeView x:Name="treeViewBlue" Grid.Row="1" Foreground="Blue" Background="{StaticResource ButtonBrushOrange}" ItemsSource="{Binding Source={StaticResource BlueDataProvider}, XPath=.}" >
            </TreeView>
        </StackPanel>
        <StackPanel Name="ListStackPanel" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="0" Grid.RowSpan="2" Grid.Column="2" Grid.ColumnSpan="1" >
            <ListBox x:Name="fishBox" BorderThickness="2" BorderBrush="Black"  
                     ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                     ItemsSource="{Binding Source={StaticResource FishBooks}}" Height="45">
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel Background="Blue"  />
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="55" />
                                <RowDefinition/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                            <Image Source="Fish\diver.png" Height="35" Grid.Row="0" />
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </StackPanel>
    </Grid>
</Window>
 
 
 
WINDOW1.XAML.CS
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.IO;
using System.IO.IsolatedStorage;
using System.Threading;
using System.Windows.Threading;
 
 
 
namespace Wpf_SomethingFishy
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        ScaleTransform st = new ScaleTransform(3, 3);
//        object dummyNode = null;
 
        #region Window Management
 
        public Window1()
        {
            InitializeComponent();
            FishController fishcontroller = new FishController();
        }
 
        #endregion Window Management
 
 
 
 
        #region Button Events
 
        void btnGo_Click(object sender, RoutedEventArgs e)
        {
            //             AddPhotosInFolder();
         }
 
 
        #endregion Button Events
 
 
    }
 
}
 
 
BBLUE NAV ITEMS.XML - This binds via Hiearchical DataTempalte and it works
 
<?xml version="1.0" encoding="utf-8" ?>
<NavItems Header="Blue Ocean Fish">
  <NavItem Type="Big Fish">
    <NavItem1 SubType="Friendly Fish ">
        <Fish>Bottom Fish</Fish>
      </NavItem1>
    <NavItem1 SubType="Deep Sea Fish">
      <Fish>Bottom Fish</Fish>
    </NavItem1>
  </NavItem>
  <NavItem Type="Little Fish">
    <NavItem1 SubType="Friendly Fish ">
      <Fish>Bottom Fish</Fish>
    </NavItem1>
    <NavItem1 SubType="Deep Sea Fish ">
      <Fish>Bottom Fish</Fish>
    </NavItem1>
  </NavItem>
</NavItems>
 
 
The PING files in the attached ZIP were also RESOURCES in the solution so they can be used as icons for the TreeView items.

Open in new window

Fish.zip
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
regarding the collection, I already gave reply to
http://www.experts-exchange.com/Microsoft/Development/Microsoft_Programming/WPF_and_Silverlight/Q_24586234.html#a24911984  
and to get images in listbox you can replace textblock in datatemplate with following

<Image Source="{Binding Path=FullPath}" Height="35" Grid.Row="0" />  

<ListBox x:Name="fishBox" BorderThickness="2" BorderBrush="Black"  
                     ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                     ItemsSource="{Binding Source={StaticResource FishBooks}}" Height="250" >
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel Background="Blue"  />
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <!--<Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="55" />
                                <RowDefinition />
                                <RowDefinition />
                            </Grid.RowDefinitions>-->
                            <!--<TextBlock Background="Aqua" >
                                <TextBlock.Text>
                                    <Binding Path="Path"/>
                                </TextBlock.Text>
                            </TextBlock>-->
                            <Image Source="{Binding Path=FullPath}" Height="35" Grid.Row="0" />
                        <!--</Grid>-->
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial