C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[9]: DataBindingのDataSourceがNothing


(過去ログ 121 を表示中)

[トピック内 11 記事 (1 - 11 表示)]  << 0 >>

■72495 / inTopicNo.1)  DataBindingのDataSourceがNothing
  
□投稿者/ Totty (1回)-(2014/06/12(Thu) 12:45:24)

分類:[VB.NET/VB2005 以降] 

 はじめまして。
Tottyと申します。今回は宜しくお願い致します。

 Windows7sp1(32bit)にてVisualStudio2008・VB.NETにて
フォームアプリケーションを作成しております。

 フォーム上にデータベースから取得した値を
項目ごとにテキストボックスに表示し、データの変更が
あった場合は背景色を変更する処理を入れようと思ってますが、
バインド時のイベント発生でエラーが発生してしまいます。

===== ソースコード =====
Option Strict Off
Option Explicit On
Public Class Form1
 Private _dt As DataTable

 Private Sub Text_TextChanged(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs)
  Dim dtRow As DataRow

  With DirectCast(eventSender, TextBox)
   dtRow = .DataBindings("text").DataSource.Rows(0)  ←※ここでエラー

   ' 内容変更時、背景色変更
   .BackColor = If(.Text = _
       dtRow(.DataBindings("text").BindingMemberInfo.BindingField, _
        DataRowVersion.Original).ToString, _
      Color.White, _
      Color.Yellow)
  End With

  ・・・・
 End Sub

 Private Sub Form1_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load
  _dt = New DataTable()

  ' イベントバンドラ登録
  For Each tmpControl As Control In Me.Controls
   Select Case True
    Case TypeOf tmpControl Is TextBoxBase
     With DirectCast(tmpControl, TextBoxBase)
      .Visible = False
      AddHandler .TextChanged, AddressOf Text_TextChanged
     End With
   End Select
  Next

  ・・・・
 End Sub

 Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
  da = New SqlDataAdapter([データを取得するクエリ], cn)
  _dt.Clear()
  da.Fill(_dt)

  ' テキストボックスとバインド
  With TextBox1
   .Visible = True
   .DataBindings.Add("text", _
       _dt, _
       "fullname", _
       True, _
       DataSourceUpdateMode.Never)  ←ここを呼び出し時に
  End With
  With TextBox2
   .Visible = True
   .DataBindings.Add("text", _
       _dt, _
       "address", _
       True, _
       DataSourceUpdateMode.Never)
  End With

  ・・・・
 End Sub

 '***** 実験的にいれた部分
 Private Sub Button1_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Button1.Click
  da = New SqlDataAdapter([他のデータを取得するクエリ], cn)
  _dt.Clear()
  da.Fill(_dt)

  ' テキストボックスと再バインド
  With TextBox1
   .DataBindings.Clear()
   .Visible = False
   .DataBindings.Add("text", _
       _dt, _
       "fullname", _
       True, _
       DataSourceUpdateMode.Never)  ←Visible = Falseでもイベント発生
   .Visible = True
  End With
  With TextBox2
   .DataBindings.Clear()
   .Visible = False
   .DataBindings.Add("text", _
       _dt, _
       "address", _
       True, _
       DataSourceUpdateMode.Never)
   .Visible = isAtVisible
  End With

  ・・・・
 End Sub
End Class
===== ソースコード =====

 デバッグをしました所、TextBox1.DataBindings.Addが呼び出された時点では
バインドが完了していないようで、Text_TextChanged内で
DirectCast(eventSender, TextBox).DataBindings("text").DataSourceが
Nothingになっていました。
Visible = Trueでないとバインドが設定できないという話が
他のページにてありましたので、Visible = TrueをDataBindings.Addの後に
行ったところ、Text_TextChangedイベントがVisible = Trueにした時に
発生し、DirectCast(eventSender, TextBox).DataBindings("text").DataSourceも
ちゃんと設定されていました。ところが、「次のデータを表示」などのボタン
(Button1)を押下して、このまま続けて別のデータを取得し再バインドを
行うとVisible = FalseでもText_TextChangedイベントが発生し、
DirectCast(eventSender, TextBox).DataBindings("text").DataSourceが
Nothingになっていました。

 バインドがVisible = Trueでないとできないということは
ないようですが、DataBindingsのDataSourceが取得できない時期が
まちまちの理由がわからず対処に困っております。
どなたか原因のおわかりになる方がいらっしゃいましたら
宜しくお願い致します。

引用返信 編集キー/
■72497 / inTopicNo.2)  Re[1]: DataBindingのDataSourceがNothing
□投稿者/ WebSurfer (288回)-(2014/06/12(Thu) 15:29:05)
No72495 (Totty さん) に返信

>  フォーム上にデータベースから取得した値を
> 項目ごとにテキストボックスに表示し、データの変更が
> あった場合は背景色を変更する処理を入れようと思ってますが、
> バインド時のイベント発生でエラーが発生してしまいます。

誰がどこのデータを変更するのですか? 第三者が DB 内のデータを変更するのではないですよね?

それから、エラーメッセージは重要な情報を含んでいることが多いので、きちんと書きましょう。

ところで DB は何ですか?
引用返信 編集キー/
■72498 / inTopicNo.3)  Re[2]: DataBindingのDataSourceがNothing
□投稿者/ Totty (3回)-(2014/06/12(Thu) 16:03:35)
 WebSurfer さん返信ありがとうございます。
申し訳ありません。情報が不足してました。


No72497 (WebSurfer さん) に返信
> ■No72495 (Totty さん) に返信
>
>> フォーム上にデータベースから取得した値を
>>項目ごとにテキストボックスに表示し、データの変更が
>>あった場合は背景色を変更する処理を入れようと思ってますが、
>>バインド時のイベント発生でエラーが発生してしまいます。
>
> 誰がどこのデータを変更するのですか? 第三者が DB 内のデータを変更するのではないですよね?
 部署内で使用するアプリケーションですので、
部署内のアプリケーション使用者が社内のデータベースを変更します。

> それから、エラーメッセージは重要な情報を含んでいることが多いので、きちんと書きましょう。
 エラーメッセージは

"オブジェクト参照がオブジェクト インスタンスに設定されていません。"

と表示されます。先ほど書き間違えてしまったのですが、DataSourceではなく
DirectCast(eventSender, TextBox).DataBindings("text")がNothingとなっているので、
.DataSourceも.DataSource.Rows(0)も取得できないためエラーが
発生しているようです。


> ところで DB は何ですか?
 DBはSQLServer2008です。

引用返信 編集キー/
■72499 / inTopicNo.4)  Re[3]: DataBindingのDataSourceがNothing
□投稿者/ WebSurfer (289回)-(2014/06/12(Thu) 16:25:09)
No72498 (Totty さん) に返信
>  部署内で使用するアプリケーションですので、
> 部署内のアプリケーション使用者が社内のデータベースを変更します。

ということは、例えば A さんがアプリを起動して DB にアクセスしデータ
を DataTable に取得してテキストボックスに表示してた後、B さんが DB
の当該データを変更したときに「背景色を変更」したいということですか?

そもそもそれは無理だと思いますが? A さんが定期的に変更がないか DB
に問い合わせるようなことをすれば可能かもしれませんが、そういうことは
考えてないですよね?


> "オブジェクト参照がオブジェクト インスタンスに設定されていません。"

それはかなり初歩的な問題ですので、デバッガを使ってどれが Nothing にな
っているか調べ、その原因を調べれば容易に自己解決できると思います。

逆に、回答者の方は、デバッガが使えませんので、探すのは容易ではありま
せん。

引用返信 編集キー/
■72502 / inTopicNo.5)  Re[4]: DataBindingのDataSourceがNothing
□投稿者/ Totty (4回)-(2014/06/12(Thu) 17:48:41)
 WebSurfer さん、再度返信ありがとうございます。
文章がよくなかったようです。

No72499 (WebSurfer さん) に返信
> ■No72498 (Totty さん) に返信
>> 部署内で使用するアプリケーションですので、
>>部署内のアプリケーション使用者が社内のデータベースを変更します。
>
> ということは、例えば A さんがアプリを起動して DB にアクセスしデータ
> を DataTable に取得してテキストボックスに表示してた後、B さんが DB
> の当該データを変更したときに「背景色を変更」したいということですか?
>
> そもそもそれは無理だと思いますが? A さんが定期的に変更がないか DB
> に問い合わせるようなことをすれば可能かもしれませんが、そういうことは
> 考えてないですよね?
 あ、そこまでは考えてません。
分担作業のために使用するので別の人間によるレコードの同時更新は行わないので
あくまで、更新する担当者がその時に変更した箇所を示すためのものです。


>>"オブジェクト参照がオブジェクト インスタンスに設定されていません。"
>
> それはかなり初歩的な問題ですので、デバッガを使ってどれが Nothing にな
> っているか調べ、その原因を調べれば容易に自己解決できると思います。
>
> 逆に、回答者の方は、デバッガが使えませんので、探すのは容易ではありま
> せん。
 そうなのです。初歩的なことなので困っております。
最初の文章がよくなかったので意図が伝わらず申し訳ありませんでした。
 対象のテキストボックスのイベントハンドラを登録(TextChangedイベント)しており、
データベースの値がTextプロパティに設定されるタイミングで登録されている
イベントハンドラのText_TextChangedが呼ばれるのは当然であるのですが、
その呼ばれたText_TextChangedの中からテキストボックスにバインドされている情報を
見ようとするとNothingとなっているのです。

 (1)TextBox1.Visibie = True
  ↓
 (2)TextBox1.DataBindings.Add データベースの値が.Textに設定
  ↓
 (3)TextChanged    ※ここでsender.DataBindings("text")がNothing

 その現象がVisibleがFalseの時だと
データベースの値がTextプロパティに設定されるタイミングで登録されているで
イベントハンドラのText_TextChangedが呼ばれずにVisibleの変更のタイミングで
Text_TextChangedが呼ばれ、その中からテキストボックスにバインドされている情報を
見るとNothingではなく設定されているのです。

 (1)TextBox1.DataBindings.Add データベースの値が.Textに設定
  ↓
 (2)TextBox1.Visibie = True  このタイミングでTextChangedイベントが発動
  ↓
 (3)TextChanged    ※この時はsender.DataBindings("text")がNothingではない。

 さらに.Visibie = Falseであれば必ず同じようになるのかと思えば、同じルートによる
再バインディングの際は.Visibie = Falseでも挙動が変わってしまい、
データベースの値がTextプロパティに設定されるタイミングで登録されている
イベントハンドラのText_TextChangedが呼ばれ、その呼ばれたText_TextChangedの中から
テキストボックスにバインドされている情報を見ようとするとNothingとなっているのです。

 (1)TextBox1.DataBindings.Clear
  ↓
 (2)TextBox1.Visibie = False
  ↓
 (3)TextBox1.DataBindings.Add 再バインド データベースの値が.Textに設定
  ↓             .VisibleがFalseでも
  ↓             このタイミングでTextChangedイベントが発動
  ↓
 (4)TextChanged    ※ここではsender.DataBindings("text")がNothing!!
  ↓
 (5)TextBox1.Visibie = True

 Nothingになっている箇所はわかっているのですが、挙動と取得できる内容が
変わってしまうのがDataBindingの設定の仕方の問題なのか仕様なのかが
わからず質問をさせて頂いた次第です。いろいろと情報が不足しておりまして
申し訳ありませんでした。何かおわかりになりますようでしたら宜しくお願い致します。
引用返信 編集キー/
■72504 / inTopicNo.6)  Re[5]: DataBindingのDataSourceがNothing
□投稿者/ Hongliang (201回)-(2014/06/12(Thu) 18:18:36)
タイミングがばらばらになるのはまあそういうものと認識しておくぐらいで。

データソースを差し替えるなら、DataBindings.Clear(/Remove)->DataBindings.Addするよりも、
直接バインディングするのは固定のBindingSourceにしておいて、
そのBindingSourceのDataSourceを差し替えるようにするのはいかがでしょうか。
引用返信 編集キー/
■72505 / inTopicNo.7)  Re[6]: DataBindingのDataSourceがNothing
□投稿者/ Totty (5回)-(2014/06/12(Thu) 18:26:19)
 Hongliang さん、返信ありがとうございます。


No72504 (Hongliang さん) に返信
> タイミングがばらばらになるのはまあそういうものと認識しておくぐらいで。
 なるほど。確かにタイミングより.DataBindings("text")が取得できれば
解決しますので、そのように認識するように致します。


> データソースを差し替えるなら、DataBindings.Clear(/Remove)->DataBindings.Addするよりも、
> 直接バインディングするのは固定のBindingSourceにしておいて、
> そのBindingSourceのDataSourceを差し替えるようにするのはいかがでしょうか。
 承知しました。ソースを修正して動作を確認してみます。
状況がわかり次第、報告致します。
引用返信 編集キー/
■72516 / inTopicNo.8)  Re[7]: DataBindingのDataSourceがNothing
□投稿者/ WebSurfer (290回)-(2014/06/13(Fri) 13:39:44)
No72505 (Totty さん) に返信

> 分担作業のために使用するので別の人間によるレコードの同時更新は行わないので
> あくまで、更新する担当者がその時に変更した箇所を示すためのものです。

単純にユーザーが TextBox に表示されている内容を変更した時点で、DataTable 内のデータの
オリジナル値と照らし合わせて TextBox の背景色を変更すれば良いと理解します。


> データベースの値がTextプロパティに設定されるタイミングで登録されている
> イベントハンドラのText_TextChangedが呼ばれるのは当然であるのですが、
> その呼ばれたText_TextChangedの中からテキストボックスにバインドされている情報を
> 見ようとするとNothingとなっているのです。

初期表示の際、データがバインドされる前に Text_TextChanged ハンドラが呼ばれるので、ハ
ンドラ内でデータソースを取得しようとしても Nothing になってしまい、NullReferenceException
がスローされるという理解でいいのでしょうか?

その理解で合っていれば、Text_TextChanged ハンドラを TextBox.TextChanged イベントに
アタッチするタイミングを、データバインドが完了した後にすれば解決するのではないです
か?

引用返信 編集キー/
■72517 / inTopicNo.9)  Re[7]: DataBindingのDataSourceがNothing
□投稿者/ WebSurfer (291回)-(2014/06/13(Fri) 13:46:58)
No72505 (Totty さん) に返信

追伸です。

もし、何らかの事情でイベントハンドラをアタッチするタイミングは変えられないと言う事情
があればハンドラ内で Nothing か否か(データバインド前かどうか)をチェックして、Nothing
なら何もしないで return するようにしてはいかがですか?
引用返信 編集キー/
■72520 / inTopicNo.10)  Re[8]: DataBindingのDataSourceがNothing
□投稿者/ Totty (6回)-(2014/06/13(Fri) 15:45:32)
 Hongliang さん、返信ありがとうございます。
返信が遅くなりまして申し訳ありません。

 Hongliang さんよりご教示頂きましたBindingSource使用ですが、
DataBindings.Add ⇒ DataSource再設定に置き換えてみました所、
挙動・取得内容共に同じでした。DataSourceを設定した時にイベントが
発生しているので取得できてもよいのですが.....。
挙動は思ったようになりませんでしたが、DataSource差し替えは
BindingSourceのDataSourceを差し替えでできることがわかりました。
勉強になりました!ありがとうございました。


 WebSurfer さん、返信ありがとうございます。
再度返信ありがとうございます。

>>分担作業のために使用するので別の人間によるレコードの同時更新は行わないので
>>あくまで、更新する担当者がその時に変更した箇所を示すためのものです。
>
> 単純にユーザーが TextBox に表示されている内容を変更した時点で、DataTable 内のデータの
> オリジナル値と照らし合わせて TextBox の背景色を変更すれば良いと理解します。
 おっしゃる通りです。DataTableのオリジナル値と照らし合わせる際に
カラム名を取得するためにバインドのデータを取得しようと思った次第です。


>>データベースの値がTextプロパティに設定されるタイミングで登録されている
>>イベントハンドラのText_TextChangedが呼ばれるのは当然であるのですが、
>>その呼ばれたText_TextChangedの中からテキストボックスにバインドされている情報を
>>見ようとするとNothingとなっているのです。
>
> 初期表示の際、データがバインドされる前に Text_TextChanged ハンドラが呼ばれるので、ハ
> ンドラ内でデータソースを取得しようとしても Nothing になってしまい、NullReferenceException
> がスローされるという理解でいいのでしょうか?
 こちらもおっしゃる通りです。.DataBindings.Add中なのでバインドが
完了していないと考えればデータソースが取得できないのも当然なのかもしれません。


> その理解で合っていれば、Text_TextChanged ハンドラを TextBox.TextChanged イベントに
> アタッチするタイミングを、データバインドが完了した後にすれば解決するのではないですか?
>
> もし、何らかの事情でイベントハンドラをアタッチするタイミングは変えられないと言う事情
> があればハンドラ内で Nothing か否か(データバインド前かどうか)をチェックして、Nothing
> なら何もしないで return するようにしてはいかがですか?
 ご教示頂いた内容を試してみようと思います。結果がわかり次第ご報告いたします。
引用返信 編集キー/
■72553 / inTopicNo.11)  Re[9]: DataBindingのDataSourceがNothing
□投稿者/ Totty (7回)-(2014/06/16(Mon) 19:41:03)
 WebSurfer さんよりご教示頂きました内容にて
無事に解決することができました。
イベントハンドラを登録する箇所を変えられない理由はありませんが
今回はDataBindings("text")がNothingの時はreturnをする方法を
使用させて頂きます。
WebSurfer さん、ありがとうございました。

 併せて、DataSource差し替えをご教示頂きました
Hongliang さんもありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -