- PR -

Windowsアプリにおけるデータ操作

1
投稿者投稿内容
えも
会議室デビュー日: 2002/10/20
投稿数: 3
投稿日時: 2002-10-20 14:56
いつも拝見させて頂いています。
Windowsアプリにおける以下のデータ操作について御教授願います。

XMLファイルをデータファイルとしたWindowsアプリ(C#)を開発しています。
1レコード1画面でTextBoxやComboBox等を多々配置しており、他レコードへはTreeViewを利用して移動する構成です。

1.レコード更新前に「保存しますか?」のメッセージを表示させて、保存/Cancelの処理分岐をさせたい。
MS-Accessのようにレコード更新前イベントがあれば、その中で処理の判断をできます。DataTableやCurrencyManagerクラスのイベントで同等のことができないものかと調べたのですが、更新後に発生するイベントばかりなのでメッセージ表示による更新Cancel等の処理を実行できないようです。ベタにやるとすれば、各TextBox等のChangeイベントで更新フラグを設定させるのだろうか?と思うのですが、より良い方法はないものでしょうか?

2.複数フォームによるDataSetの共有。
コンポーネントクラスを利用して、DataSetのインスタンスを作っておけば、複数画面でDataSetを共有できるのではないかと思うのですが、なかなかうまくいきません。できれば、デザイン時のDataSoruceプロパティにそのDataSetが表示されるようになれば効率よく開発もできるのだと思います。
DataSetの共有方法についてご存知の方教えて頂けますでしょうか。

以上宜しくお願いします。
うりゅう
大ベテラン
会議室デビュー日: 2002/06/15
投稿数: 202
お住まい・勤務地: Hiroshima
投稿日時: 2002-10-21 08:32
えもさん、こんにちは。うりゅうです。

>ベタにやるとすれば、各TextBox等のChangeイベントで更新フラグを設定させるのだろうか?と思うのですが、より良い方法はないものでしょうか?

 DataSetを用いるならば、もっとスマートな設計が可能だと思います。DataSetに対して追加や更新をかけても、DataAdapterのUpdateメソッドを用いない限り元のデータは更新されないわけですから、Updateメソッドを動かす直前に保存/Cancelの処理分岐を入れるようすれば問題ないと思われます。
 仮にDataSetのデータが更新されていたとしても、「更新を行った行のみ」「追加された行のみ」「元のデータ」「現在のデータ」などの行状態(Rowstate)をDatasetは保持していますのでどのようにでも処理できるかと思われます。

>コンポーネントクラスを利用して、DataSetのインスタンスを作っておけば、複数画面でDataSetを共有できるのではないかと思うのですが
 コンポーネントクラスを利用して、DataAdapterや、Datasetを定義しておけば、フォームごとやページごとに定義を行う必要が無く便利ですが、コンポーネントクラスはイベントを伴わないため、コンポーネントクラスそのものでDataSetのインスタンスを作ることは不可能ではないでしょうか?
 DataSetを共有するならば、一番最初に必要になるイベントをもつフォーム内に置いて、「Shared」をつけて宣言すれば、その後のフォームに置いても値を保持したまま利用できます。WEBにおけるセッション変数に近い利用が出来る、共有変数扱いですが、ちょっとニーズと違いますか?

参考になれば、幸いです。


_________________
--------------------------------------
ネットビルド 小田原貴樹
odahara@netbuiuld.jp
--------------------------------------
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2002-10-21 08:50
こんにちは

>>1.レコード更新前に「保存しますか?」のメッセージを表示させて、
>> 保存/Cancelの処理分岐をさせたい。

 DataRow(DataSetのDataTableのDataRow)にStateプロパティー(RowState列挙型)があります。これを見れば、追加、更新、削除のステータスがとれます。
 DataSetは、簡単or乱暴には、データベースの更新用複製と考えてください。1レコードずつ「更新しますか?」と尋ねるのではなく、データベース(関係するテーブル群)単位で尋ねる方が、ユーザもプログラマも負担が少なくてすみます。

 ちょっと動作を考えてみてください。・・・
データが表示されています。その中のたとえば百行のデータを更新します。ここで、カーソルを動かして、データを入力しようとすると「更新しますか?(Yes/No)」…これを百回も繰り返さなければなりません。気をつけていただきたいのは、多くの人がキーボードから手を離してマウスで「Yes」のボタンをクリックする、ということです。
・・・えもさんのポストからは、このような操作が想像されるのですが、使う立場になったとき、このような操作をしたいですか?
えも
会議室デビュー日: 2002/10/20
投稿数: 3
投稿日時: 2002-10-21 11:39
うりゅうさん・Jittaさん、ご返答ありがとうございます。

1.レコード更新前…について
 DataSet、DataRow、Stateのいづれを利用しても、やはり単一のレコード更新前のイベント取得は困難なようですね。
Stateについては簡単にしか確認してませんが、やはりレコード更新後にStateが変わるようです。
 1レコード/1画面構成であれば、変更前にメッセージ表示というのは私の中では極普通かと思っていましたが…。Gridなんかを利用した表形式であれば、確かに各行単位でメッセージ表示はしませんけど。

 DataSetを利用する場合、レコード単位での更新はあまり意識せずにテーブル単位での更新を意識すべきなのであろう、ということは薄々感じてはいましたが、返答を見てあらためてそうなのであろうと思いました。せっかく.NETを利用するのですから、それに合わせたプログラムを考えてインタフェースも工夫していこうと思います。

2.複数フォームによるDataSetの共有。
>DataSetを共有するならば、一番最初に必要になるイベントをもつフォーム内に置いて、「Shared」をつけて宣言すれば、その後のフォームに置いても値を保持したまま利用できます。
 フォームからダイアログを開く時に、そのダイアログ内のinternal変数(手抜きでプロパティにしなかった…)にDataSetを渡すことでデータ共有を実現していました。返答とは見方が違うようですが、特定フォーム内にDataSetを保有してこれを利用するしかない、ということで納得できました。特定フォームのDataSetをShareする方がスマートなんでしょうかね? ちょっと考えてみます。

かなり参考になりました。特に1については、意識の持ち方の違いなので一人悩んでいたらドツボに嵌ってたかもしれません。
どうもありがとうございました。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2002-10-21 13:06
引用:

えもさんの書き込み (2002-10-21 11:39) より:
 1レコード/1画面構成であれば、変更前にメッセージ表示というのは私の中では極普通かと思っていましたが…。


 昔、Windows以前のCUI環境であれば、それでよかったでしょう。しかし、GUI環境は違うのです。
 実際に、客先IT担当者との打ち合わせで、「CUIしか知らない人たちがさわるから、それでよい」と言われて作り、半年の開発期間の間にエンドユーザがWindows操作になれ、エンドユーザからクレームをつけられたことがあります。ユーザの負担とデータの保護は、ある意味、相反する要因ですが、ユーザの負担を減らす(かつ、開発者の負担も減る)ことを優先するように考えてみてください。また、ユーザ操作はその他のアプリケーションにあわせることを優先してください(Windowsロゴの取得、みたいな項目を参照してみてください)。
えも
会議室デビュー日: 2002/10/20
投稿数: 3
投稿日時: 2002-10-21 14:45
Windowsロゴ取得の文書…、いつかは見ようと思いつつ見てませんでした。
ちょっと本題からずれてしまいますが、データ登録確認メッセージの表示タイミングについての確認を少々。

 Outlookの連絡先やメール、またLotusではありますけど一般的アプリのノーツの文書。これらは、それぞれの別フォルダへの移動(Outlook)やDBを閉じる(Notes)タイミングでなく、個々の文書を閉じる時に保存確認のメッセージを表示しているかと思います。
 私がやりたかったのは、まさにこのようなタイミングでの保存確認なのですが、やっぱりイレギュラーな方法でしょうか? くどくて申し訳ありませんが、ちょっと気になるところではありますので、何かしらコメントがあればお願い致します。
 「イレギュラー」とのことであれば、やはり考えをあらためてWindowsロゴの文書でも眺めようかと…。
うりゅう
大ベテラン
会議室デビュー日: 2002/06/15
投稿数: 202
お住まい・勤務地: Hiroshima
投稿日時: 2002-10-21 16:26
>DataSet、DataRow、Stateのいづれを利用しても、やはり単一のレコード更新前のイベント取得は困難なようですね。

いやいや、結局レコードの更新につけなんにつけ、Updateメソッドを発行しない限り、実際の更新は起こらないのですから、好きにコーディングできると思うのですが。

>レコード単位での更新はあまり意識せずにテーブル単位での更新を意識すべきなのであろう

確かにくどいのはくどいでしょうね。しかし、1レコード単位の確認が必要なこともあるでしょう。
 1レコード単位の更新確認だとして、DataBindingを使っていると、DataSetの中身そのものは自動的に変更されてしまいますので、「更新完了」ボタンか何かをつくって、それを押したときにダイアログを表示し、その戻りが「OK」だったら、Updateメソッドを発行するればいいのではないかと思います。
_________________
--------------------------------------
ネットビルド 小田原貴樹
odahara@netbuiuld.jp
--------------------------------------
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2002-10-21 17:42
引用:

えもさんの書き込み (2002-10-21 14:45) より:

 Outlookの連絡先やメール、またLotusではありますけど一般的アプリのノーツの文書。これらは、それぞれの別フォルダへの移動(Outlook)やDBを閉じる(Notes)タイミングでなく、個々の文書を閉じる時に保存確認のメッセージを表示しているかと思います。
 私がやりたかったのは、まさにこのようなタイミングでの保存確認なのですが、やっぱりイレギュラーな方法でしょうか?


 なるほど。それはもう、「設計思想」としか言いようがないと思います。クライアント(客先)からしっかりと要望事項を聞き出し、一律の設計思想に則って設計してください。「不用意なデータ更新を最大限に防止する」という思想の基に作り、クライアントの了解を得れば、それでいいのではないでしょうか(だだし、一貫性は必要です)。ただこの場合も、実際に使ってみると「やっぱりいちいち聞かれるのは面倒」と言われれることも考慮しておくと、ベターだと思います。

 イベントに関してですが、用意されているコンポーネント(DataRowぐらいでよいと思います)を継承して別のコンポーネントを作り、更新前に発生するイベントを追加してはいかがでしょうか。具体的な方法は提示できませんが、検討してみてください。

#DataTableのColumnChangingイベントは、ごらんになりました?「変更中」に発生するようです
1

スキルアップ/キャリアアップ(JOB@IT)