■ カレントディレクトリのパスが変わってしまう
参考:http://genz0.blogspot.com/2007/11/net_27.html
SaveFileDialogを使って、CSVファイルを保存。
その後、何かしらのDB参照を行うと、エラー。
なんて症状に2時間悩まされ、見つけた症状。
SaveFileDialogでパスを指定すると、それがアプリケーションのカレントパスになってしまうらしい。
FileDialog.RestoreDirectory=true
で回避できる。
デフォルトでカレントパスが変わるというのもどうかと思うが・・・
■ 画面のちらつき防止
コンボを切り替えるごとに動的コントロールを再表示していると、画面がぱらぱらぱらぱら・・・
●SuspendLayout() ~ ResumeLayout()
よく使われる手段。
なんかあるなぁ・・・と気にせず使っていたが、大して効果が無いような気がする。
ちなみに、今回はパネルの中で再表示しているので、
Me.SuspendLayout()だと、フォームに対してしているから意味がない。
panel.SuspendLayout()が正しい。
結果はまったく変わらなかったが・・・
ResumeLayout(False)という設定もできる。勘違いしてこっちを使ったら、スクロールバーが出ない現象に悩まされる。
●ダブルバッファとやらを使った方法
参考:http://www.atmarkit.co.jp/fdotnet/dotnettips/197doublebuf/doublebuf.html
↓をフォームロード時に追加するらしい
Me.SetStyle(ControlStyles.DoubleBuffer, True)
Me.SetStyle(ControlStyles.UserPaint, True)
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
ただし、パネル内のコントロールには効かない。プロパティの設定もフォームにしかできない。・・・なぜ?
調べると、SetStyleメソッドはプロテクトメソッドなので、フォームクラス内からいじれないから、らしい。
Panelクラスを継承したハンドメイドPanelクラスを作り、その中でSetStyleを指定して云々・・・
参考:http://jumbofoot.cocolog-nifty.com/yass_vbnet_tips/2005/10/post_b019.html
:http://blogs.wankuma.com/yo/archive/2008/05/27/139673.aspx
:http://social.msdn.microsoft.com/Forums/ja-JP/csharpexpressja/thread/d2130848-0dd9-491e-9e8d-6df2ba155d9b
表示するコントロールの数が少ないやつには少しだけ有効だったが、多いものには効かず。。。
パネルを上に重ねて描画中は見えなくする・・・とか、せこい方法を色々と考えたが、
描画が終わるタイミングを取るとかしないと駄目なので、よりいっそうの深みにハマりそうだったので挫折。
●BeginUpdate メソッドとEndUpdate メソッドを使う方法。
http://joomla.hiros-dot.net/windows-/2010-05-11-04-02-45/combobox/42-2010-06-04-16-48-58.html
→リストボックス、もしくはコンボボックスにしか有効ではないみたい・・・。゜(゜´Д`゜)゜。
参考:http://dobon.net/vb/dotnet/control/lbitemsadd.html
●WindowsAPIを使った方法があった。
→ http://codezine.jp/article/detail/3407
http://youryella.wankuma.com/Library/Extensions/Control/Updating.aspx
要点
・Imports System.Runtime.InteropServices インポートする
・SendMessageの宣言(Public sheard)
・&HB = 0x000b(WinAPIに送るメッセージ内容)
・panel.Reflesh()で再描画した内容を表示する
土日をはさんで大変時間がかかった・・・
■ 画面クローズ時のちらつき
A画面→B画面で、B画面を×とかで閉じると、A画面に要素が多い為か、B画面が徐々に消えてちらつく。
B画面に下記設定で解決。
悩んだ割りにあっさり解決方法があって、大変に時間を無駄にした。。
初期及び、Close時(今回は初期化は不要なのでしていない)
Me.Opacity = 0
画面のActive時
Me.Refresh()
Me.Opacity = 100
参考:http://dobon.net/vb/bbs/log3-18/11158.html
■ TabIndexの順番
参考:http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard19.htm
特に意識しなくても勝手に「順番」が振られる。順番には色々と種類があるらしい。
TabIndexは設定方法に優先順位がある、らしい。
・ タブオーダー:フォームにコントロールを配置したときに振られる。
ただし、ZオーダーやTabIndexの順番を変更することで後からこの順番を変更することができる。
・ Zオーダー :重なり方の順番
・ TabIndex :TabIndexプロパティで指定する順番
■ テキストの選択
TextBox.select()とか、Panel.Select()で選択状態にできる。
TextBoxの中の文字を選択状態にしたい場合、
TextBox.SelectAll()でOK、かと思ったが、選択にならない。
TextBox.Select()
TextBox.SelectAll()
これで思ったような挙動になった。なんか面倒くさい。。。
ちなみに、TextBox.Select(Start , Length)で選択開始と選択文字数を選択できる。
■ DirectCastとか
動的に作ったコントロールをNameプロパティで探すとき使う。
Ctypeというのも有るが、微妙に挙動が違うらしい。調べていると、Directcastのほうが安全とか何とか・・・。
コントロール名で動的コントロールを探す↓
Dim controlsFind() As Control
controlsFind = フォーム.Controls.Find("コントロール名", True)
Return DirectCast(controlsFind(0), TextBox)
コントロール名を指定して、値を返す関数を作ってみた。
'-----------------------------------------------------------------------------------------------------------------------------------
'コントロール名を指定して、値を取得する
'引 数:フォーム(参照),コントロールの種類↓,インデックス,コントロール名,取得したいコントロールの種類
' :0:TextBox 1:Label 2:Button 3:CheckBox(Checked)
'戻り値:成功:コントロール 失敗:Nothing
'機 能:動的コントロールを返す
'-----------------------------------------------------------------------------------------------------------------------------------
Function getDinamicControls(ByRef form As Form, ByVal no As Integer, _
ByVal index As Integer, ByVal strControlName As String)
Try
Dim controlsFind() As Control
Select Case no
Case 0 'TextBox
controlsFind = form.Controls.Find(strControlName & index, True)
Return DirectCast(controlsFind(0), TextBox)
Case 1 'Label
controlsFind = form.Controls.Find(strControlName & index, True)
Return DirectCast(controlsFind(0), Label)
Case 2 'Button
controlsFind = form.Controls.Find(strControlName & index, True)
Return DirectCast(controlsFind(0), Button)
Case 3 'CheckBox
controlsFind = form.Controls.Find(strControlName & index, True)
Return DirectCast(controlsFind(0), Label)
Case Else
Return Nothing
End Select
Catch ex As Exception
MessageBox.Show(ex.Message, PUBLIC_STR_CAPTION, MessageBoxButtons.OK,
MessageBoxIcon.Error)
Throw
End Try
End Function
意外だったのが、DirectCastで返した値が参照値だったこと。
値を取得するだけの一方通行っぽいが、ちゃんと動的コントロールに設定できた。
うーん、ちょっと危険?
Controls.Find()はあくまで配列を返す。複数の同じ名前のコントロールをVBは容認しているということか?
Nothingが返ってきた場合どうするの?と思い、調べると、
obj Is Nothingで判定できるらしい。
参考:http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=28458&forum=7
他にも、o Is Nothing = False、Not IsNothing(o)、IsNothing(o) = Falseなど。
苦し紛れにNothing返してるのが微妙だが・・・。
例外を発生させてみる?
Return Nothing → Throw New ApplicationException
■ Double型に変換できる?
参考:http://dobon.net/vb/dotnet/vb2cs/isnumeric.html
TextBoxに入っている数値がDouble型にできるものかチェックするとき、便利なDouble.TryParse 。
詳細:http://msdn.microsoft.com/ja-jp/library/8w0x0ctx(v=VS.80).aspx
NumberStyleを指定すると、小数点、マイナス、指数表現とかを設定できる。
詳細:http://msdn.microsoft.com/ja-jp/library/system.globalization.numberstyles(v=VS.80).aspx
これはString型用で、CharだとIsNumeric、IsDateなどがある。
■ ABCD辞典
A
AddHandler Me.FormClosing, AddressOf fmMenu_FormClosing ・・・RemoveHandler を見て。
B
C
D
Dispose ・・・画面の場合、Closeと混同するが、画面.FormClosingイベントが起こらないので、やはり別物(当然)
画面.Close 後に、画面.Disposeしよう。
E
e.Cansel ・・・イベントキャンセル。イベントハンドラ内で。Exit Subだけじゃイベントはキャンセルされません。
F
G
H
I
J
K
L
Leaveイベント LostFocusと同じ。VS2003より前の.NETでは、LostFocus→Leave、getFocus→Enter
2003から復活しているが、Leave、Enterも健在。どちらを使えばいいのやら。。。
・・・
O
OleDbConnection.State プロパティ ・・・接続状態保持(Openとか)
P
Q
R
R
RemoveHandler Me.FormClosing, AddressOf fmMenu_FormClosing
・・・AddHandlerまで指定したイベントがおこらない。
ResumeLayout() ・・・SuspendLayoutで停止したイベントを再開
S
StartPosition = FormStartPosition.CenterScreen ・・・フォーム開始位置を中央にする
SuspendLayout() ・・・レイアウト変更に伴うイベントを停止(ResumeLayout)
参考:http://genz0.blogspot.com/2007/11/net_27.html
SaveFileDialogを使って、CSVファイルを保存。
その後、何かしらのDB参照を行うと、エラー。
なんて症状に2時間悩まされ、見つけた症状。
SaveFileDialogでパスを指定すると、それがアプリケーションのカレントパスになってしまうらしい。
FileDialog.RestoreDirectory=true
で回避できる。
デフォルトでカレントパスが変わるというのもどうかと思うが・・・
■ 画面のちらつき防止
コンボを切り替えるごとに動的コントロールを再表示していると、画面がぱらぱらぱらぱら・・・
●SuspendLayout() ~ ResumeLayout()
よく使われる手段。
なんかあるなぁ・・・と気にせず使っていたが、大して効果が無いような気がする。
ちなみに、今回はパネルの中で再表示しているので、
Me.SuspendLayout()だと、フォームに対してしているから意味がない。
panel.SuspendLayout()が正しい。
結果はまったく変わらなかったが・・・
ResumeLayout(False)という設定もできる。勘違いしてこっちを使ったら、スクロールバーが出ない現象に悩まされる。
●ダブルバッファとやらを使った方法
参考:http://www.atmarkit.co.jp/fdotnet/dotnettips/197doublebuf/doublebuf.html
↓をフォームロード時に追加するらしい
Me.SetStyle(ControlStyles.DoubleBuffer, True)
Me.SetStyle(ControlStyles.UserPaint, True)
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
ただし、パネル内のコントロールには効かない。プロパティの設定もフォームにしかできない。・・・なぜ?
調べると、SetStyleメソッドはプロテクトメソッドなので、フォームクラス内からいじれないから、らしい。
Panelクラスを継承したハンドメイドPanelクラスを作り、その中でSetStyleを指定して云々・・・
参考:http://jumbofoot.cocolog-nifty.com/yass_vbnet_tips/2005/10/post_b019.html
:http://blogs.wankuma.com/yo/archive/2008/05/27/139673.aspx
:http://social.msdn.microsoft.com/Forums/ja-JP/csharpexpressja/thread/d2130848-0dd9-491e-9e8d-6df2ba155d9b
表示するコントロールの数が少ないやつには少しだけ有効だったが、多いものには効かず。。。
パネルを上に重ねて描画中は見えなくする・・・とか、せこい方法を色々と考えたが、
描画が終わるタイミングを取るとかしないと駄目なので、よりいっそうの深みにハマりそうだったので挫折。
●BeginUpdate メソッドとEndUpdate メソッドを使う方法。
http://joomla.hiros-dot.net/windows-/2010-05-11-04-02-45/combobox/42-2010-06-04-16-48-58.html
→リストボックス、もしくはコンボボックスにしか有効ではないみたい・・・。゜(゜´Д`゜)゜。
参考:http://dobon.net/vb/dotnet/control/lbitemsadd.html
●WindowsAPIを使った方法があった。
→ http://codezine.jp/article/detail/3407
http://youryella.wankuma.com/Library/Extensions/Control/Updating.aspx
要点
・Imports System.Runtime.InteropServices インポートする
・SendMessageの宣言(Public sheard)
・&HB = 0x000b(WinAPIに送るメッセージ内容)
・panel.Reflesh()で再描画した内容を表示する
土日をはさんで大変時間がかかった・・・
■ 画面クローズ時のちらつき
A画面→B画面で、B画面を×とかで閉じると、A画面に要素が多い為か、B画面が徐々に消えてちらつく。
B画面に下記設定で解決。
悩んだ割りにあっさり解決方法があって、大変に時間を無駄にした。。
初期及び、Close時(今回は初期化は不要なのでしていない)
Me.Opacity = 0
画面のActive時
Me.Refresh()
Me.Opacity = 100
参考:http://dobon.net/vb/bbs/log3-18/11158.html
■ TabIndexの順番
参考:http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard19.htm
特に意識しなくても勝手に「順番」が振られる。順番には色々と種類があるらしい。
TabIndexは設定方法に優先順位がある、らしい。
・ タブオーダー:フォームにコントロールを配置したときに振られる。
ただし、ZオーダーやTabIndexの順番を変更することで後からこの順番を変更することができる。
・ Zオーダー :重なり方の順番
・ TabIndex :TabIndexプロパティで指定する順番
■ テキストの選択
TextBox.select()とか、Panel.Select()で選択状態にできる。
TextBoxの中の文字を選択状態にしたい場合、
TextBox.SelectAll()でOK、かと思ったが、選択にならない。
TextBox.Select()
TextBox.SelectAll()
これで思ったような挙動になった。なんか面倒くさい。。。
ちなみに、TextBox.Select(Start , Length)で選択開始と選択文字数を選択できる。
■ DirectCastとか
動的に作ったコントロールをNameプロパティで探すとき使う。
Ctypeというのも有るが、微妙に挙動が違うらしい。調べていると、Directcastのほうが安全とか何とか・・・。
コントロール名で動的コントロールを探す↓
Dim controlsFind() As Control
controlsFind = フォーム.Controls.Find("コントロール名", True)
Return DirectCast(controlsFind(0), TextBox)
コントロール名を指定して、値を返す関数を作ってみた。
'-----------------------------------------------------------------------------------------------------------------------------------
'コントロール名を指定して、値を取得する
'引 数:フォーム(参照),コントロールの種類↓,インデックス,コントロール名,取得したいコントロールの種類
' :0:TextBox 1:Label 2:Button 3:CheckBox(Checked)
'戻り値:成功:コントロール 失敗:Nothing
'機 能:動的コントロールを返す
'-----------------------------------------------------------------------------------------------------------------------------------
Function getDinamicControls(ByRef form As Form, ByVal no As Integer, _
ByVal index As Integer, ByVal strControlName As String)
Try
Dim controlsFind() As Control
Select Case no
Case 0 'TextBox
controlsFind = form.Controls.Find(strControlName & index, True)
Return DirectCast(controlsFind(0), TextBox)
Case 1 'Label
controlsFind = form.Controls.Find(strControlName & index, True)
Return DirectCast(controlsFind(0), Label)
Case 2 'Button
controlsFind = form.Controls.Find(strControlName & index, True)
Return DirectCast(controlsFind(0), Button)
Case 3 'CheckBox
controlsFind = form.Controls.Find(strControlName & index, True)
Return DirectCast(controlsFind(0), Label)
Case Else
Return Nothing
End Select
Catch ex As Exception
MessageBox.Show(ex.Message, PUBLIC_STR_CAPTION, MessageBoxButtons.OK,
MessageBoxIcon.Error)
Throw
End Try
End Function
意外だったのが、DirectCastで返した値が参照値だったこと。
値を取得するだけの一方通行っぽいが、ちゃんと動的コントロールに設定できた。
うーん、ちょっと危険?
Controls.Find()はあくまで配列を返す。複数の同じ名前のコントロールをVBは容認しているということか?
Nothingが返ってきた場合どうするの?と思い、調べると、
obj Is Nothingで判定できるらしい。
参考:http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=28458&forum=7
他にも、o Is Nothing = False、Not IsNothing(o)、IsNothing(o) = Falseなど。
苦し紛れにNothing返してるのが微妙だが・・・。
例外を発生させてみる?
Return Nothing → Throw New ApplicationException
■ Double型に変換できる?
参考:http://dobon.net/vb/dotnet/vb2cs/isnumeric.html
TextBoxに入っている数値がDouble型にできるものかチェックするとき、便利なDouble.TryParse 。
詳細:http://msdn.microsoft.com/ja-jp/library/8w0x0ctx(v=VS.80).aspx
NumberStyleを指定すると、小数点、マイナス、指数表現とかを設定できる。
詳細:http://msdn.microsoft.com/ja-jp/library/system.globalization.numberstyles(v=VS.80).aspx
これはString型用で、CharだとIsNumeric、IsDateなどがある。
■ ABCD辞典
A
AddHandler Me.FormClosing, AddressOf fmMenu_FormClosing ・・・RemoveHandler を見て。
B
C
D
Dispose ・・・画面の場合、Closeと混同するが、画面.FormClosingイベントが起こらないので、やはり別物(当然)
画面.Close 後に、画面.Disposeしよう。
E
e.Cansel ・・・イベントキャンセル。イベントハンドラ内で。Exit Subだけじゃイベントはキャンセルされません。
F
G
H
I
J
K
L
Leaveイベント LostFocusと同じ。VS2003より前の.NETでは、LostFocus→Leave、getFocus→Enter
2003から復活しているが、Leave、Enterも健在。どちらを使えばいいのやら。。。
・・・
O
OleDbConnection.State プロパティ ・・・接続状態保持(Openとか)
P
Q
R
R
RemoveHandler Me.FormClosing, AddressOf fmMenu_FormClosing
・・・AddHandlerまで指定したイベントがおこらない。
ResumeLayout() ・・・SuspendLayoutで停止したイベントを再開
S
StartPosition = FormStartPosition.CenterScreen ・・・フォーム開始位置を中央にする
SuspendLayout() ・・・レイアウト変更に伴うイベントを停止(ResumeLayout)