🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

button

HTMLで用いる<button>タグです。

WPF

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

Q&A

解決済

1回答

3137閲覧

二回目のデータの更新ができない[C#][.NET Framework 4.5.2][WPF]

Q10

総合スコア12

C#

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

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

button

HTMLで用いる<button>タグです。

WPF

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

0グッド

1クリップ

投稿2020/12/15 15:58

編集2020/12/15 17:02

C#でWPFとPostgreSQLを使ったデータベースです。
一回目は更新できるのですが、二回目は

C#

1var table = context.Cats; 2CatModel cat = this.dataGrid.SelectedItem as CatModel; 3var target = table.Single(x => x.No == cat.No); ←ここで止まる

System.Reflection.TargetException: '非静的メソッドにはターゲットが必要です。'

というエラーが出て止まってしまいます。
targetがnullになっていることは確認できています。
しかし、二回目も正しく選択しているので、値が入るはずなのですが…。
どうしたら二回目以降も更新できるようになりますか?

元のコードはこちらですが短くしました:

MainWindow.xaml

C#

1<Window x:Class="WpfApp1.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 mc:Ignorable="d" 7 Height="350" Width="530" 8 > 9 <Grid Height="350" Width="530"> 10 <Label Content="名前:" Margin="10,10,0,0"/> 11 <TextBox x:Name="search_name" Margin="56,12,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120"/> 12 <Label Content="種別:" Margin="201,10,0,0"/> 13 <ComboBox x:Name="search_kind" Margin="252,12,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="125"/> 14 <Button x:Name="search_button" Content="検索" HorizontalAlignment="Left" Margin="432,12,0,0" VerticalAlignment="Top" Width="75" Click="search_button_Click"/> 15 16 <DataGrid Name="dataGrid" HorizontalAlignment="Left" Margin="10,43,0,0" Width="497" Height="225"> 17 <DataGrid.Columns> 18 <DataGridTemplateColumn IsReadOnly="True" Header="選択" Width="50"> 19 <DataGridTemplateColumn.CellTemplate> 20 <DataTemplate> 21 <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" VerticalAlignment="Center" /> 22 </DataTemplate> 23 </DataGridTemplateColumn.CellTemplate> 24 </DataGridTemplateColumn> 25 <DataGridTextColumn Binding="{Binding Age}" ClipboardContentBinding="{x:Null}" Header="年齢" IsReadOnly="True" Width="40"/> 26 </DataGrid.Columns> 27 </DataGrid> 28 <Button x:Name="upd_button" Content="更新" HorizontalAlignment="Left" Margin="90,273,0,0" VerticalAlignment="Top" Width="75" Height="30" Click="upd_button_Click"/> 29 </Grid> 30</Window>

MainWindow.xaml.cs

C#

1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Linq; 5using System.Windows; 6 7namespace WpfApp1 8{ 9 public partial class MainWindow : Window 10 { 11 public MainWindow() 12 { 13 InitializeComponent(); 14 using (var context = new PgDbContext()) 15 { 16 var mstKind = context.Kinds; 17 IQueryable<Kind> result = from x in mstKind orderby x.KindCd select x; 18 Kind empty = new Kind(); 19 empty.KindCd = ""; 20 empty.KindName = "なし"; 21 var list = result.ToList(); 22 list.Insert(0, empty); 23 this.search_kind.ItemsSource = list; 24 this.search_kind.DisplayMemberPath = "KindName"; 25 this.search_kind.SelectedIndex = 0; 26 } 27 } 28 29 private void search_button_Click(object sender, RoutedEventArgs e) 30 { 31 Object[] param = new Object[2]; 32 param[0] = this.search_name.Text; 33 param[1] = (this.search_kind.SelectedValue as Kind).KindCd; 34 BackgroundWorker worker = new BackgroundWorker(); 35 worker.DoWork += SearchProcess; 36 worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(SearchProcessCompleted); 37 worker.RunWorkerAsync(param); 38 } 39 40 private void searchData() 41 { 42 using (var context = new PgDbContext()) 43 { 44 String searchName = this.search_name.Text; 45 String searchKind = (this.search_kind.SelectedValue as Kind).KindCd; 46 var tblCat = context.Cats; 47 IQueryable<Cat> result; 48 result = from x in tblCat 49 where x.Name.StartsWith(searchName) 50 orderby x.No 51 select x; 52 this.dataGrid.ItemsSource = result.ToList(); 53 } 54 } 55 56 private void SearchProcess(object sender, DoWorkEventArgs e) 57 { 58 using (var context = new PgDbContext()) 59 { 60 String searchName = (e.Argument as Object[])[0] as String; 61 String searchKind = (e.Argument as Object[])[1] as String; 62 var tblCat = context.Cats; 63 IQueryable<Cat> result; 64 result = from x in tblCat 65 where x.Name.StartsWith(searchName) 66 orderby x.No 67 select x; 68 List<CatModel> resultList = new List<CatModel>(); 69 foreach (Cat cat in result.ToList()) 70 { 71 resultList.Add(new CatModel(cat.No, cat.Name, cat.Sex, cat.Age, cat.Kind, cat.Favorite)); 72 } 73 e.Result = resultList; 74 } 75 } 76 77 private void SearchProcessCompleted(object sender, RunWorkerCompletedEventArgs e) 78 { 79 this.dataGrid.ItemsSource = e.Result as List<CatModel>; 80 } 81 82 private void upd_button_Click(object sender, RoutedEventArgs e) 83 { 84 if (this.dataGrid.SelectedItem == null) 85 { 86 MessageBox.Show("選択してください。"); 87 return; 88 } 89 using (var context = new PgDbContext()) 90 { 91 var table = context.Cats; 92 CatModel cat = this.dataGrid.SelectedItem as CatModel; 93 var target = table.Single(x => x.No == cat.No); 94 var win = new SubWindow(cat); 95 win.Owner = GetWindow(this); 96 win.ShowDialog(); 97 searchData(); 98 } 99 } 100 } 101}

SubWindow.xaml

C#

1<Window x:Class="WpfApp1.SubWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 mc:Ignorable="d" 7 Height="300" Width="300" 8 WindowStartupLocation="CenterOwner" 9 > 10 <Grid> 11 <Label Content="年齢:" Margin="10,98,0,0"/> 12 <TextBox x:Name="txt_age" Margin="61,98,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="50"/> 13 <Button x:Name="btn_mod" Content="更新" HorizontalAlignment="Left" Margin="205,231,0,0" VerticalAlignment="Top" Width="75" Click="btn_mod_Click" Visibility="Collapsed"/> 14 </Grid> 15</Window>

SubWindow.xaml.cs

C#

1using System.Linq; 2using System.Windows; 3 4namespace WpfApp1 5{ 6 public partial class SubWindow : Window 7 { 8 public CatModel SelectedCat { set; get; } 9 public SubWindow(CatModel SelectedCat) 10 { 11 InitializeComponent(); 12 using (var context = new PgDbContext()) 13 { 14 var mstKind = context.Kinds; 15 IQueryable<Kind> result = from x in mstKind orderby x.KindCd select x; 16 var list = result.ToList(); 17 this.SelectedCat = SelectedCat; 18 this.Title = "更新"; 19 this.btn_mod.Visibility = Visibility.Visible; 20 this.txt_age.Text = SelectedCat.Age.ToString(); 21 } 22 } 23 24 private void btn_mod_Click(object sender, RoutedEventArgs e) 25 { 26 using (var context = new PgDbContext()) 27 { 28 var table = context.Cats; 29 var target = table.Single(x => x.No == SelectedCat.No); 30 target.Age = int.Parse(this.txt_age.Text); 31 context.SaveChanges(); 32 MessageBox.Show("更新しました。"); 33 } 34 this.Close(); 35 } 36 } 37}

PgDbContext.cs

C#

1using Npgsql; 2using System.Data.Entity; 3 4namespace WpfApp1 5{ 6 class PgDbContext : DbContext 7 { 8 private const string ConnectionString = "Server=localhost;User ID=USER01;Password=USER01;Database=DB01;port=5432"; 9 public PgDbContext() : base(new NpgsqlConnection(ConnectionString), true) { } 10 public DbSet<Kind> Kinds { get; set; } 11 public DbSet<Cat> Cats { get; set; } 12 protected override void OnModelCreating(DbModelBuilder modelBuilder) 13 { 14 modelBuilder.HasDefaultSchema("dora"); 15 Database.SetInitializer<PgDbContext>(null); 16 } 17 } 18}

App.config
Kind.cs
Cat.cs
とテーブルはこちらから、
CatModel.cs はこちらからコピペして下さい。
※10,000字に入らなかったので、ご面倒をお掛けして申し訳ないです。

使い方
「検索」をクリックしてデータを表示します。
データを一つ選んで「更新」をクリックします。
年齢を変更して「更新」をクリックします。(一回目は成功)
データを一つ選んで「更新」をクリックします。
年齢を変更して「更新」をクリックします。(二回目は失敗)←期待する動作(二回目も成功)

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

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

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

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

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

guest

回答1

0

ベストアンサー

catがnullになっていませんか?
asによるキャストは失敗してもnullを返すだけなので、失敗するはずのない、失敗する場合を考慮していないキャストの場合は(T)によるキャストを用いると良いでしょう。(前置き記法だから書きにくい気持ちも分かりますが)

投稿2020/12/29 05:27

Ram.Type-0

総合スコア424

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

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

Q10

2021/01/11 09:44

ご回答ありがとうございます。 (返信遅くなり申し訳ありません。連休中はPCを触れませんでした。) upd_button_Click()の中身を変更してみました。 「(T)によるキャスト」というのを以下のように書いてみました: //CatModel cat = this.dataGrid.SelectedItem as CatModel; // Before CatModel cat = (CatModel)this.dataGrid.SelectedItem; // After このようにすると、一回目は正常に更新できるのですが、 二回目は以下のエラーが出ました: System.InvalidCastException: '型 'WpfApp1.Cat' のオブジェクトを型 'WpfApp1.CatModel' にキャストできません。' まず、「(T)によるキャスト」というのは上記の変更で良かったでしょうか? また、(CatModel)でエラーが出る理由をご存知でしょうか? すみませんが宜しくお願い致します。
Ram.Type-0

2021/01/11 11:51

(T)によるキャストはその変更で合っています。 エラーは、CatのオブジェクトをCatModelにキャストしようとしているが、CatはCatModelを継承していないのでそのキャストは無効、できないよ、ということを言っています。 ここでCatModelにキャストしようとしているものはthis.dataGrid.SelectedItemになりますので、 2回目以降の更新時にのみthis.dataGrid.SelectedItemにCatModelではなくCat型のオブジェクトが入ってしまっているということでしょう。
Q10

2021/01/11 13:12

なるほど!お陰様で解決しました! >2回目以降の更新時にのみthis.dataGrid.SelectedItemにCatModelではなくCat型のオブジェクトが入ってしまっているということでしょう。 .GetType()で調べると、仰る通り、一回目はCatModel型、二回目はCat型でした。 そして、CatModel型とCat型の一番の違いは"IsChecked"の有無でした。 更に、表示されるDataGridをよく見ると、 検索ボタン押下直後は"IsChecked"があるのに、 更新ボタン押下直後は"IsChecked"が消えていました(!)。 (このことから、更新後に毎回検索ボタンを押せば、正しく動作することが判明しました。) 暫定対策として、更新ボタン押下直後に検索ボタン押下したときの命令群をコピペしました。 これで正しく動作するようになりました。 本当なら恒久対策としてCatModel型とCat型の齟齬を無くすとか、 二つのモデルを一つにするとかしないといけないんでしょうが、これは宿題とさせて下さい。 質問するまでにもいろいろ試したのですが、 どこから手を付けていいのか全く見当がつきませんでした。 質問して良かったです。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問