質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
DataGrid

GUIの一種であり、データを表の形式でみることが可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

4819閲覧

【C#】【WPF】【SQLite】DataGridに入力したデータをSQLiteで更新したい

noppa

総合スコア2

DataGrid

GUIの一種であり、データを表の形式でみることが可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2021/12/23 06:45

前提・実現したいこと

初めて投稿します。C#初心者です。現在サイトや本で調べながらアプリケーションを制作しています。
言葉などが変な場合があるかもしれません。ご了承頂ければと思います。

WPFにDataGridをセットし、SQLiteを使用してテーブルを取得して表示させています。
DataGridへSQLiteでDataTableからObservableCollectionにしてバインディングしています。

また、DataGridに直接データを入力し、入力完了のタイミングでテーブルを更新したいと考えています。

発生している問題・エラーメッセージ

色々サイト等を調べてSQLiteでDataTableを使用してDataGridに表示する事までは出来ましたが、 DataGridに直接データ入力後にテーブルを更新する方法が調べても方法が分かりませんでした。

該当のソースコード

XAML

1<Window x:Class="SqlDataTable.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:SqlDataTable" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="450" Width="450"> 9 <Grid> 10 <DataGrid x:Name="DataGrid" ItemsSource="{Binding}" HorizontalAlignment="Left" Margin="10,10,0,10" Width="200" AutoGenerateColumns="False"> 11 <DataGrid.Columns> 12 <DataGridTextColumn Binding="{Binding BindingName}" Header="氏名" Width="100"></DataGridTextColumn> 13 <DataGridTextColumn Binding="{Binding BindingComment}" Header="コメント" Width="100"></DataGridTextColumn> 14 </DataGrid.Columns> 15 </DataGrid> 16 17 </Grid> 18</Window> 19

C#

1using System; 2using System.Linq; 3using System.Windows; 4using System.Windows.Controls; 5using System.Data; 6using System.Collections.ObjectModel; 7using System.Data.SQLite; 8 9 10namespace SqlDataTable 11{ 12 /// <summary> 13 /// MainWindow.xaml の相互作用ロジック 14 /// </summary> 15 public partial class MainWindow : Window 16 { 17 DataTable table = new DataTable(); 18 ObservableCollection<NameClass> Names = new ObservableCollection<NameClass>(); 19 20 public MainWindow() 21 { 22 InitializeComponent(); 23 24 25 using (SQLiteConnection connection = new SQLiteConnection("Data Source=Database.db")) 26 { 27 try 28 { 29 connection.Open(); 30 } 31 catch (Exception e) 32 { 33 MessageBox.Show(e.Message); 34 } 35 } 36 37 table = DataBaseLoad(); 38 39 var t = from range in table.AsEnumerable() select range; 40 foreach (var range in t) 41 { 42 NameClass name = new NameClass(); 43 name.BindingName = range.Field<string>("氏名"); 44 name.BindingComment = range.Field<string>("コメント"); 45 Names.Add(name); 46 } 47 DataGrid.DataContext = this.Names; 48 } 49 50 public DataTable DataBaseLoad() 51 { 52 using (SQLiteConnection connection = new SQLiteConnection("Data Source=Database.db")) 53 { 54 var dt = new DataTable(); //検査員用データテーブル作成 55 var adapter = new SQLiteDataAdapter("SELECT * FROM t_table", connection); //SQL実行 56 57 adapter.Fill(dt); 58 59 return dt; 60 } 61 } 62 } 63 64 public class NameClass 65 { 66 public string BindingName { get; set; } 67 public string BindingComment { get; set; } 68 } 69} 70

試したこと

DataTableだとDataAdapterのUpdateメソッドを使用すれば良いと思ったので、ObservableCollectionとDataTableとで中身を比較して、無いデータをDataTableに挿入すれば良いのかと考え、foreachで回してみましたが、DataTable側に要素が一つ足りないので例外が発生してしまいました。
何か根本的に違う気がしています。
DataGridへの入力後のイベントはObservableCollectionの変更通知かDataGridのCellEditEndingイベントを考えています。

ObservableCollectionからDataTableへ変換する方法はあるのでしょうか。
それとも最初のDataGridへの入力の時点から間違っているのでしょうか。
よろしくお願いします。

補足情報(FW/ツールのバージョンなど)

使用ツール:Visual Studio Express 2017
.NET Framework Version 4.61

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TN8001

2021/12/23 08:25

(わたしはDB関係全然わかっていませんが) DataTableを使うなら、そのままDataGridにバインドすればよくないですか?
退会済みユーザー

退会済みユーザー

2021/12/23 08:36

どうしても WPF ということでなければ Windows Form + 型付 DataSet/DataTable/TableAdapter + DataGridView にしてはいかが? 以下の記事の図1と図2を見てください。図2の DataSet の左側に DaraGridView があるという形になります。 DB 設計者のための明解 ADO.NET 第 1 回 https://docs.microsoft.com/ja-jp/previous-versions/cc482903(v=msdn.10)
noppa

2021/12/23 09:09

TN8001様 ご回答頂きありがとうございます。 そのままDataGridにバインドについては、行幅固定・行ヘッダがテーブルと違う為ObservableCollectionを使用しました。(テーブルの値だけを表示したかったです) SurferOnWww様 ご回答頂きありがとうございます。 WPFを使用した理由については初めてC#を使用する為、FormよりWPFの方がいいかなと安易に考えた事と、画面を最大化した場合、表示が崩れる為です。 (通常画面と最大化画面で比率を保ちたい)
TN8001

2021/12/23 09:46

> そのままDataGridにバインドについては、行幅固定・行ヘッダがテーブルと違う為ObservableCollectionを使用しました。 一部だけ出したいということであれば、今と同じようにDataGridTextColumn等を作るだけですよ? Binding="{Binding カラム名}" とDataTableのカラム名で指定もできますし、 Binding="{Binding [0]}" とインデクサでもいいです。 カラム名に記号類が入る可能性がある場合は、インデクサが安全かもしれません。 [DataGridとDataTable(その2)【WPF編】 | 泥庭](https://yone64.wordpress.com/2014/12/05/datagrid%e3%81%a8datatable%ef%bc%88%e3%81%9d%e3%81%ae2%ef%bc%89%e3%80%90wpf%e7%b7%a8%e3%80%91/ [data binding - What is it about DataTable Column Names with dots that makes them unsuitable for WPF's DataGrid control? - Stack Overflow](https://stackoverflow.com/questions/2940618/what-is-it-about-datatable-column-names-with-dots-that-makes-them-unsuitable-for --- 「DataTableを使うこと自体どうなんだ?」って話なんでしょうか? わたしはその辺わかりません^^; かずきさんは5年前にこうおっしゃっていますが、今も同意見かはわかりません。 [DataTable の バインディングでの更新方法](https://social.msdn.microsoft.com/Forums/vstudio/ja-JP/8615aae9-f1e8-4429-b838-ff11983d47ff/datatable-12398#1ac68bf3-722c-419f-9c14-ce38182a7563
noppa

2021/12/24 01:16

TN8001様 ご回答頂きありがとうございます。 >一部だけ出したいということであれば、今と同じようにDataGridTextColumn等を作るだけですよ? > >Binding="{Binding カラム名}" とDataTableのカラム名で指定もできますし、 >Binding="{Binding [0]}" とインデクサでもいいです。 思いつきませんでした・・・ よくよく考えてみれば、ObservableCollectionとやっている事は同じですね。 DataTable(DBのテーブル)のカラム名をバインドする事で思った通りの動作をする事ができました。 大変勉強になりました。ありがとうございました。 この内容で問題解決してしまいましたので解決方法の方にDBの更新も含めてソースコードを記載致します。
guest

回答1

0

自己解決

質問への追記・修正の依頼にて問題が解決致しましたので修正したソースコードを記載致します。
ご回答頂いたTN8001様、SurferOnWww様ありがとうございました。

XAMLは変更ありませんのでC#のみ記載致します。

C#

1using System; 2using System.Linq; 3using System.Windows; 4using System.Windows.Controls; 5using System.Data; 6using System.Collections.ObjectModel; 7using System.Data.SQLite; 8 9 10namespace SqlDataTable 11{ 12 /// <summary> 13 /// MainWindow.xaml の相互作用ロジック 14 /// </summary> 15 public partial class MainWindow : Window 16 { 17 DataTable table = new DataTable(); 18 SQLiteDataAdapter adapter; 19 SQLiteConnection connection; 20 21 public MainWindow() 22 { 23 InitializeComponent(); 24 25 connection = new SQLiteConnection("Data Source=Database.db"); 26 27 try 28 { 29 connection.Open(); 30 } 31 catch (Exception e) 32 { 33 MessageBox.Show(e.Message); 34 } 35 adapter = new SQLiteDataAdapter("SELECT * FROM t_table", connection); //SQL実行 36 table = DataBaseLoad(); 37 table.RowChanged += new DataRowChangeEventHandler(Table_RowChanged); 38 DataGrid.DataContext = table; 39 } 40 41 private void Table_RowChanged(object sender, DataRowChangeEventArgs e) 42 { 43 DataBaseUpload(table); 44 } 45 46 public DataTable DataBaseLoad() 47 { 48 DataTable dt = new DataTable(); 49 adapter.Fill(dt); 50 return dt; 51 } 52 53 public void DataBaseUpload( DataTable table) 54 { 55 SQLiteCommandBuilder commandBuilder = new SQLiteCommandBuilder(adapter); 56 adapter.Update(table); 57 } 58 } 59 60 public class NameClass 61 { 62 public string BindingName { get; set; } 63 public string BindingComment { get; set; } 64 } 65} 66

ObservableCollectionを使用せずDataTableのみとしました。
DataTable(データベース)のカラム名をバインドしています。
データベースのテーブルを読込み・更新両方を使用しますので、adapterとconnectionは共通としました。

投稿2021/12/24 01:25

noppa

総合スコア2

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問