简体   繁体   中英

Binding ObservableCollection<T> ItemSource to DataGrid

In my wpf application, I am using Prism library to autowire my viewmodel into my view. I have this working for simple properties which automatically binds view and model. Now I am trying to bind an ObservableCollection<T> data to bind into DataGrid with no luck. Below is my structure for current scenario.

ConfigurationDetails.cs

public class ConfigurationDetails:BindableBase
{
    private int _id;
    public int Id { get { return _id; } set { SetProperty(ref _id, value); } }

    private string _configFName;
    private string _configSName;
    private string _configUName;

    public string ConfigFName { get { return _configFName; } set { SetProperty(ref _configFName, value); } }
    public string ConfigSName { get { return _configSName; } set { SetProperty(ref _configSName, value); } }
    public string ConfigUName { get { return _configUName; } set { SetProperty(ref _configUName, value); } }
}

ConfigurationWindowViewModel.cs

public class ConfigurationWindowViewModel : BindableBase
{
    public ConfigurationWindowViewModel()
    {
        ConfigDetails = new ObservableCollection<ConfigurationDetails>();
    }
    private ObservableCollection<ConfigurationDetails> _configDetails;
    public ObservableCollection<ConfigurationDetails> ConfigDetails { get { return _configDetails; } set { SetProperty(ref _configDetails, value); } }
}

ConfigurationWindow.xaml

<UserControl x:Class="MyApp.Views.ConfigurationWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        HorizontalContentAlignment="Center">
    ....
    <DataGrid ItemsSource="{Binding ConfigDetails}" AutoGenerateColumns="False">
         <DataGrid.Columns>
              <DataGridTextColumn Header="F NAME" Width="*" Binding="{Binding Path=ConfigFName}"/>
              <DataGridTextColumn Header="S NAME" Width="*" Binding="{Binding Path=ConfigSName}"/>
              <DataGridTextColumn Header="U NAME" Width="*" Binding="{Binding Path=ConfigUName}"/>
         </DataGrid.Columns>
    </DataGrid>
    ....
</UserControl>

ConfigurationWindow.xaml.cs

public ConfigurationWindow()
{
     InitializeComponent();
     using (_db = new MyEntities())
     {
         var configRecords = _db.tblConfigs.ToList().Select(x => new ConfigurationDetails()
         {
              ConfigFName = x.ConfigFName,
              ConfigSName = x.ConfigSName,
              ConfigUName = x.ConfigUName,
              Id = x.ConfigID
         });
         model.ConfigDetails = new ObservableCollection<ConfigurationDetails>(configRecords);
         //model.ConfigDetails will have records assigned to it when debugged
        }
     }
 }

But still, I don't see any records displayed in my DataGrid . What is it am missing here. I have also used ViewModelLocator.AutoWireViewModel and it has been working flawlessly for other model properties. Hope to get some help here.

Update - I have my ConfigurationWindowViewModel.cs placed in ViewModels folder. Sorry for missing that to mention.

Where are you adding the ConfigurationDetails objects to the ConfigDetails collection? Try to add some items in the constructor of the ConfigurationWindowViewModel class:

public class ConfigurationWindowViewModel : BindableBase
{
   public ConfigurationWindowViewModel()
   {
    ConfigDetails = new ObservableCollection<ConfigurationDetails>();
    //add some items...:
    ConfigDetails.Add(new ConfigurationDetails() { ConfigFName = "F", ConfigSName = "S", ConfigUName = "U" });
    ConfigDetails.Add(new ConfigurationDetails() { ConfigFName = "F", ConfigSName = "S", ConfigUName = "U" });
    ConfigDetails.Add(new ConfigurationDetails() { ConfigFName = "F", ConfigSName = "S", ConfigUName = "U" });
   }
   private ObservableCollection<ConfigurationDetails> _configDetails;
   public ObservableCollection<ConfigurationDetails> ConfigDetails { get { return _configDetails; } set { SetProperty(ref _configDetails, value); } }
}

And for the autowire functionality in Prism to work out-of-the-box you need to follow the default naming conventions, ie your ConfigurationWindowViewModel class should be located in a "ViewModels" folders (and in the .ViewModels namespace) in the root folder of your project. Please refer to Brian Lagunas' blog post for more information about this and how you could change the default conventions by calling the ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver method in your Bootstrapper or App.xaml.cs: http://brianlagunas.com/getting-started-prisms-new-viewmodellocator/

Also make sure that your implements the IView interface:

public partial class ConfigurationWindow() : Window, IView
{
...
}

Well... First of all ObservableCollection implements INotifyPropertyChanged, so you don't have to do that.

Then this is enough:

public ObservableCollection<ConfigurationDetails> ConfigDetails { get; set; } 


public ConfigurationWindow()
{
   InitializeComponent();
   using (_db = new MyEntities())
   {
      var configRecords = _db.tblConfigs.ToList().Select(x => new ConfigurationDetails()
     {
          ConfigFName = x.ConfigFName,
          ConfigSName = x.ConfigSName,
          ConfigUName = x.ConfigUName,
          Id = x.ConfigID
     });
     foreach(var config in configRecords)
     { 
        model.ConfigDetails.Add(config);
      }


    }
 }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM