简体   繁体   中英

Binding a DataTable to a DataGrid in MVVM WPF

I'm quite new to the whole C# .net thing, but I searched a lot and I can't find how to make it work.

I have a DataGrid in my view, like this :

<DataGrid Name="SettingGrid" ItemsSource="{Binding Path=PluginSettings, Mode=OneWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="True" Margin="224.4,10,10,10"/>

PluginSettings is a DataTable, dynamically filled with different columns and row depending on what the user is doing. The PluginSettings is always up to date, I have checked that with the debug mode, the columns and row are always how I want them. But the view is never updated. After some Googling, I found that DataTable is not enumerable, so can not be binded to. I changed my binding to {Binding Path=PluginSettings.DefaultView . With that, I get the rows working perfectly, but the columns aren't.

When I add a column to my DataTable, the view never shows it. And if I understood correctly what DefaultView is, it means I can't replicate the change the user do on the Grid to the actual DataTable to save them, and that's actually my goal.

Did I miss something ? Is it just a bad choice to use DataGrid, is there something better for what I am trying to do ?

Hoping I made what I mean clear, English is not my first language. Thanks

  • I must mention that the use of System.Data within client-side code (WPF) is discouraged.
  • This includes System.Data.DataSet , System.Data.DataTable , and any other classes inside the System.Data namespace.
  • You should create proper data models and use that instead.
  • IMO, System.Data is a server-side concept and should not be carried over to the client.
  • in WinRT, for example, it doesn't even exist. There's no System.Data , so if you ever plan to migrate your WPF application to WinRT, you'll have a lot of code to rewrite.

Having said that, this example works in both adding new rows and adding new columns:

<Window x:Class="MiscSamples.DataGridAndDataTable"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DataGridAndDataTable" Height="300" Width="300">
    <DockPanel>
        <Button Content="Add Column" DockPanel.Dock="Top" Click="AddColumn"/>
        <Button Content="Add Row" DockPanel.Dock="Top" Click="AddRow"/>
        <DataGrid Name="SettingGrid" 
              ItemsSource="{Binding}" 
              AutoGenerateColumns="True"/>
    </DockPanel>
</Window>

Code Behind:

  public partial class DataGridAndDataTable : Window
    {
        public DataTable PluginSettings { get; set; }

        public DataGridAndDataTable()
        {
            InitializeComponent();

            PluginSettings = new DataTable();

            PluginSettings.Columns.Add("Name", typeof (string));
            PluginSettings.Columns.Add("Date", typeof(DateTime));

            PluginSettings.NewRow();
            PluginSettings.NewRow();

            PluginSettings.Rows.Add("Name01", DateTime.Now);

            DataContext = PluginSettings;
        }

        private void AddColumn(object sender, RoutedEventArgs e)
        {
            PluginSettings.Columns.Add("Age", typeof (int));
            DataContext = null;
            DataContext = PluginSettings;
        }

        private void AddRow(object sender, RoutedEventArgs e)
        {
            PluginSettings.Rows.Add("Name01", DateTime.Now);
        }
    }

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