Search code examples
wpflistviewitemtemplate

ListView ItemTemplate and ItemsSource don't show expected value



I got a Problem with the following code:

FolderBrowserDialog ofd = new FolderBrowserDialog();
        ofd.Description = "Wählen Sie bitte den Ordner mit den Videodateien die Sie verschieben und umbenennen wollen...";
        if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
            string path = ofd.SelectedPath;
            foreach (var file in Directory.GetFiles(path)) {
                files.Add(new FileStatus(file, new FileInfo(file).Length));
            }
        }

The Code of the FileStatus object is:

public FileStatus(string filename, long filesize, long currentsize = 0) {
        this.currentsize = currentsize;
        this.filename = filename;
        this.filesize = filesize;
    }
    public string filename { get; set; }
    public long filesize { get; set; }
    public long currentsize { get; set; }
    public double percent {
        get {
            return (currentsize / filesize) * 100;
        }
    }

The XAML of the ListView is:

<ListView Name="lb_data" Grid.Row="2" DataContext="{Binding}" ItemTemplate="{StaticResource fileStatusTemp}">
    </ListView>

The XAML of fileStatusTemp:

<DataTemplate x:Key="fileStatusTemp">
        <StackPanel>
            <TextBlock Text="{Binding Path=filename}" ></TextBlock>
        </StackPanel>
</DataTemplate>

The ItemSource-property is set in the constructor of the window:

lb_data.ItemSource = files;

Thanks to KDiTraglia, for the advice :)
So the Problem is that when I run this code it doesn't displays the filename. It just shows nothing. In another project a similiar piece of code works...
I hope you can help me :)
Greetings Knerd


Solution

  • You are missing an itemssource="{binding ??}" in your list view. I am also skeptical as to whether this line is working as you intend...

    DataContext="{Binding}"
    

    Edit:

    I copied this all into a test project and it works fine, here's my entire project verbatim, maybe I did something small.

    dowhilefor makes a good point about INotifyPropertyChanged, my code works on load, but would not work if the files were added from an event other than the constructor. To fix this easily, just change List to ObservableCollection (don't forget to include 'using System.Collections.ObjectModel'). I updated my code below.

    public partial class MainWindow : Window
    {
        public ObservableCollection<FileStatus> files { get; set; }
        public MainWindow()
        {
            InitializeComponent();
            files = new ObservableCollection<FileStatus>();
            lb_data.ItemsSource = files;
    
            FolderBrowserDialog ofd = new FolderBrowserDialog();
            ofd.Description = "Wählen Sie bitte den Ordner mit den Videodateien die Sie verschieben und umbenennen wollen...";
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string path = ofd.SelectedPath;
                foreach (var file in Directory.GetFiles(path))
                {
                    files.Add(new FileStatus(file, new FileInfo(file).Length));
                }
            }
        }
    }
    

    -

    <Window x:Class="WPFtest5.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <DataTemplate x:Key="fileStatusTemp">
                <StackPanel>
                    <TextBlock Text="{Binding Path=filename}" />
                </StackPanel>
            </DataTemplate>
        </Window.Resources>
        <ListView Name="lb_data" ItemTemplate="{StaticResource fileStatusTemp}"/>
    </Window>
    

    -

    public class FileStatus
    {
        public FileStatus(string filename, long filesize, long currentsize = 0)
        {
            this.currentsize = currentsize;
            this.filename = filename;
            this.filesize = filesize;
        }
        public string filename { get; set; }
        public long filesize { get; set; }
        public long currentsize { get; set; }
        public double percent
        {
            get
            {
                return (currentsize / filesize) * 100;
            }
        }
    
    }