首页 > 解决方案 > Trying to move data binding from MainWindow.xaml.cs to another ViewModel module

问题描述

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

标签: c#wpfxamlmvvmdata-binding

解决方案


您应该设置TableDat视图模型的属性。为此,您只需var从构造函数中删除关键字:

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),
        };
    }
}

然后,您可以将 的ItemsSource属性绑定到使用以下语法返回的视图模型DataGrid的属性:TableDatObservableCollection<LineViewModel>{Binding}

<DataGrid ItemsSource="{Binding TableDat}" ... />

推荐阅读