1

I am trying to create a table of values that arrive from serial port. Table will update as soon as new data arrives at the serial port.

So far there is only one xaml file.

I have been following this implementation which worked so far but only when I assign an array of objects to the DataGrid in the MainWindow.xaml.cs (as in that example), which used to look like this:

public MainWindow()
       {
           InitializeComponent();             

            var TableDat = new ObservableCollection<LineViewModel>()
            {
            new LineViewModel(1,2,888,6,5), // Random values to see if anyhting dipslays
            new LineViewModel(122,2,888,6,5),
            };        

            this.dataGrid1.ItemsSource = TableDat ;
    }

DataGrid in XAML looked like this:

  <DataGrid AutoGenerateColumns="False" 
        Height="Auto" 
        HorizontalAlignment="Left" 
        Name="dataGrid1" 
        VerticalAlignment="Top" 
        ScrollViewer.CanContentScroll="True" 
        ScrollViewer.VerticalScrollBarVisibility="Visible"
        Grid.Row="1">

        <DataGrid.Columns >
            <DataGridTextColumn Binding="Item1" Width="*">
            <DataGridTextColumn Binding="Item2" Width="*" />
            <DataGridTextColumn Binding="Item3" Width="*" />
            <DataGridTextColumn Binding="Item4" Width="*" />
            <DataGridTextColumn Binding="Item5" Width="*" />
        </DataGrid.Columns>
    </DataGrid>

I wanted to divide my project into what I believe to be a correct MVVM layout with seperate folders for Models, ViewModels, View files and not everything happening from within the Main class.

I want the whole structure to roughly resemble
View<-> ViewModel <-> Model

To do that I created another file DataGridViewModel.cs which would instantiate object array and pass it to the dataGrid1 DataGrid.

This is my MainWindow.xaml.cs

 public partial class MainWindow : Window {           

        private DataGridViewModel _dat = new DataGridViewModel();               

        public MainWindow()
        {     
           InitializeComponent();
           DataContext = _dat;
        }
}

This is class from which I would like to pass the object array to the mentioned DataGrid.

class DataGridViewModel : ObservableObject
    {            
        public ObservableCollection<LineViewModel> TableDat { get; private set; }

        public DataGridViewModel()
        {
            var TableDat = new ObservableCollection<LineViewModel>()
            {                    
                new LineViewModel(1,2,888,6,5),
                new LineViewModel(122,2,888,6,5),
            };

            //Here I would like to pass the object array to the data grid, dataGrid1
        }           
    }

Now

this.dataGrid1.ItemsSource = TableDat;

Yields:

Severity Code Description Project File Line Suppression State Error CS1061
'DataGridViewModel' does not contain a definition for 'dataGrid1' and no accessible
 extension method 'dataGrid1' accepting a first argument of type 'DataGridViewModel' 
could be found(are you missing a using directive or an assembly reference ?)

Which I guess is because I am trying to pass it to MainWindow.xaml and not DataGrid.xaml.

If I change this to MainWindow and try with

MainWindow.dataGrid1.ItemsSource = TableDat;

which I would hope it would link it to the appropriate xaml file I get:

Severity Code Description Project File Line Suppression State Error CS0120
An object reference is required for the non-static field, method, or property 
'MainWindow.dataGrid1'

I am new to object-oriented stuff and many of these concepts are way over my head at the moment so forgive me if am not formulating what I am trying to say corectly nor using the correct terminology.

I'm at the point of defeat and accepting that if I managed to pass the array correctly from my MainWindow.xaml.cs, I might as well just do it there and everything else too, rather then spend few more days (weeks) trying to figure out how to do this correctly or at all.

thanks

mega_creamery
  • 667
  • 7
  • 19
  • 1
    Assigning the ItemsSource property in code behind isn't data binding. Write this in XAML: ``. The Binding looks up the TableDat property in the current DataContext, i.e. in the `_dat` object that you assigned to it. Done. – Clemens Oct 09 '18 at 14:58
  • Also read [Data Binding Overview](https://learn.microsoft.com/en-us/dotnet/framework/wpf/data/data-binding-overview). – Clemens Oct 09 '18 at 15:04
  • It is databindig, at least for cells. – Luis Oct 09 '18 at 21:57

1 Answers1

1

You should set the TableDat property of your view model. To do this you simply need to remove the var keyword from the constructor:

class DataGridViewModel : ObservableObject
{
    public ObservableCollection<LineViewModel> TableDat { get; private set; }

    public DataGridViewModel()
    {
        TableDat = new ObservableCollection<LineViewModel>()
        {
            new LineViewModel(1,2,888,6,5),
            new LineViewModel(122,2,888,6,5),
        };
    }
}

You could then bind the ItemsSource property of the DataGrid to the TableDat property of the view model that returns the ObservableCollection<LineViewModel> using the {Binding} syntax:

<DataGrid ItemsSource="{Binding TableDat}" ... />
mm8
  • 163,881
  • 10
  • 57
  • 88
  • Well spotted. Remove the tiny `var`. As a note, the property could also be readonly: `public ObservableCollection TableDat { get; }`. If it isn't, it should fire a property change notification. – Clemens Oct 09 '18 at 15:12
  • 1
    You're a legend mm8. It works no idea how, but it hopefully that will come in time. – mega_creamery Oct 10 '18 at 08:38