small-j
small-j

Reputation: 309

wpf datagrid not showing data, but show rows

I'm trying to make a simple WPF project and I have a problem: the DataGrid is bound to an ObservableCollection, it does not show the data, but it shows the correct amount of rows.Here's how it looks

WPF DataGrid showing correct number of rows, but not showing data

Here's XAML:

<Window x:Class="008.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:008"
        mc:Ignorable="d"
        Title="MainWindow">

    <StackPanel>
        <StackPanel Orientation="Horizontal" Margin="10">
            <Button Name="AddButton" HorizontalAlignment="Left"  Margin="10">Add an element</Button>
            <Button Name="DeleteOldButton" HorizontalAlignment="Left" Margin="10">Delete old files</Button>
            <Button Name="ShowPop" HorizontalAlignment="Left" Margin="10">Show most popular element</Button>
        </StackPanel>

        <DataGrid Name="dgrid" CanUserResizeColumns="True"
                  CanUserAddRows="False"
                  IsReadOnly="True"
                  DataContext="files"
                  ItemsSource="{Binding}"

                  Width="Auto">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                <DataGridTextColumn Header="Date created" Binding="{Binding Created}"/>
                <DataGridTextColumn Header="Times Open" Binding="{Binding TimesOpen}"/>

            </DataGrid.Columns>
        </DataGrid>

    </StackPanel>
</Window>

And here's the code:

public partial class MainWindow : Window
    {
    ObservableCollection<File> files;

    public MainWindow()
    {

        InitializeComponent();
        files = new ObservableCollection<File>();
        files.Add(new File("r", DateTime.Now));
        files.Add(new File("o", DateTime.Now));
        files.Add(new File("a", DateTime.Now));
        files.Add(new File("d", DateTime.Now));

    }

}

I've already tried setting the Window DataContext to files, it didn't work

UPD: Here's the File class:

class File
    {
       public string Name { get; set; }
       public DateTime Created { get; set; }
       public int TimesOpen { get; set; }

        public File(string s, DateTime d)
        {
            Created = d;
            Name = s;
            TimesOpen = 0;
        }
        public void Open()
        {
            TimesOpen++;
        }
    }

UPD: Implemented the INotifyPropertyChanged. Did not help. The File definition is below:

    class File: INotifyPropertyChanged 

    {
        public event PropertyChangedEventHandler PropertyChanged;
        private string name;
        public string Name
        {
            get { return name; }
            set
            {
                if (!value.Equals(name,StringComparison.InvariantCulture)) {
                    OnPropertyChanged("Name");
                    name = value;
                }                     
            }

        }
        private DateTime created;
       public DateTime Created
        {
            get { return created; }
            set
            {
                if (!created.Equals(value))
                {
                    OnPropertyChanged("Created");
                    created = value;
                }
            }
        }
        private int times_open;
       public int TimesOpen
        {
            get { return times_open; }
            set
            {
                if (times_open != value)
                {
                    OnPropertyChanged("TimesOpen");
                    times_open = value;
                }
            }
        }

        public File(string s, DateTime d)
        {
            Created = d;
            Name = s;
            TimesOpen = 0;
        }

        void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }

        public void Open()
        {
            TimesOpen++;
        }
    }
}

Upvotes: 3

Views: 4553

Answers (2)

Borophyll
Borophyll

Reputation: 1119

Try this.. MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {

        InitializeComponent();
        Files = new ObservableCollection<File>();
        Files.Add(new File("r", DateTime.Now));
        Files.Add(new File("o", DateTime.Now));
        Files.Add(new File("a", DateTime.Now));
        Files.Add(new File("d", DateTime.Now));
        DataContext = this;
    }
}

public ObservableCollection<File> Files { get; set; }

MainWindow.xaml (snippet):

<DataGrid Name="dgrid" CanUserResizeColumns="True"
                  CanUserAddRows="False"
                  IsReadOnly="True"
                  ItemsSource="{Binding Files}"
                  Width="Auto">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
        <DataGridTextColumn Header="Date created" Binding="{Binding Created}"/>
        <DataGridTextColumn Header="Times Open" Binding="{Binding TimesOpen}"/>
    </DataGrid.Columns>
</DataGrid>

Upvotes: 0

amuz
amuz

Reputation: 364

There are a few things you are doing wrong - You should set the datacontext for the window
- Your item source is bounded to files. But wait..
- Files needs to be a property in your datacontext, i.e. the mainwindow
- Additionally you should think about implementing INotifyPropertyChanged in your model

<DataGrid Name="dgrid" CanUserResizeColumns="True"
        CanUserAddRows="False"
        IsReadOnly="True"
        ItemsSource="{Binding Files}"
        Width="Auto">

    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
        <DataGridTextColumn Header="Date created" Binding="{Binding Created}"/>
        <DataGridTextColumn Header="Times Open" Binding="{Binding TimesOpen}"/>
    </DataGrid.Columns>
</DataGrid>

and in you code behind use

public partial class MainWindow : Window
{
    public ObservableCollection<File> Files {get; set;}


    public MainWindow()
    {

        InitializeComponent();
        DataContext = this;
        Files = new ObservableCollection<File>();
        Files.Add(new File("r", DateTime.Now));
        Files.Add(new File("o", DateTime.Now));
        Files.Add(new File("a", DateTime.Now));
        Files.Add(new File("d", DateTime.Now));
        Files.Add(new File("d", DateTime.Now));
        Files.Add(new File("d", DateTime.Now));
    }
}

Upvotes: 2

Related Questions