• ベストアンサー

Delphi .net ListBoxで上下キーで移動したい

Delphi .net WEB版での作成です。 LISTBOXを作成するソースがあります。 --- while 条件 do begin LstBox1.Items.Insert(Row,Text); LstList.Items.Item[Row].value := LstValue; end; --- リストボックスは作成されますが、 上下キーで項目の移動ができません。 この作成をPage_Load の度に行えばできるのですが 作成処理は重いので、作成は1回のみで行いたいです。 どのようにすればよろしいのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • SHIMAPEE
  • ベストアンサー率75% (154/203)
回答No.1

一般的なユーザインタフェースの観点からアドバイス申し上げます。 「項目の移動」というのは項目の位置を変える(項目が1234と並んでいるのを2134のようにする)ことだと推察しますけれども、通常、上下キーは項目の選択に使いますので、移動には使わない方がよいのではないでしょうか。ListBox内の項目を移動するインタフェースでよくあるのは、選択した項目を上移動ボタン、下移動ボタンで動かすというものです。 具体的には、例えばWindowsXP + Delphi2007 VCLフォームアプリケーションでは下記のようになります。WEB版でも同様な考え方でできると思います。 ----- procedure TForm1.UpButtonClick(Sender: TObject); // 上移動ボタンの処理 var ItemIndex: integer; begin ItemIndex:=ListBox1.ItemIndex; if ItemIndex>=1 then ListBox1.Items.Exchange(ItemIndex, ItemIndex-1); // 上の項目と交換 end; procedure TForm1.DownButtonClick(Sender: TObject); // 下移動ボタンの処理 var ItemIndex: integer; begin ItemIndex:=ListBox1.ItemIndex; if (ItemIndex<>-1) and (ItemIndex<(ListBox1.Items.Count-1)) then ListBox1.Items.Exchange(ItemIndex, ItemIndex+1); // 下の項目と交換 end; ----- 更に、項目が選択されていて移動できるときだけボタンをEnableにすれば、洗練されたインタフェースになるでしょう。 また、同じ項目を指定することが多いのでしたら選択した項目を自動的に一番上に移動しておく等も考えられます。(そもそも項目の位置が変わる/変えられることが使いやすいかどうかはよく考えた方がよいと思いますが)

関連するQ&A

  • Delphiでキー入力を投げたい

    ゲームコントローラに対応していないソフトウェアを、コントローラに対応させるべくプログラムを組んでいます。 Delphiのプログラムでコントローラからの入力を受け取り、該当するウインドウにメッセージを送信すればこの仕組みが実現できると考えたのです。 まず、以下の関数を記述しました。 function CallBackTest(WH: HWND; LP: LParam): BOOL stdcall; var Buff: array [0..255] of Char; begin if IsWindowVisible(WH) then if GetWindowText(WH, Buff, 255) <> 0 then TListBox(LP).Items.AddObject(Buff, Pointer(WH)); Result := True; end; 次に、ListBoxを用意して、以下を実行しました。 EnumWindows(@CallBackTest, Longint(ListBox1)); ListBoxには実行中のウインドウタイトルが表示されます。そこで、目的のウインドウ名を選択して for i := 0 to (ListBox1.Items.Count - 1) do if ListBox1.Selected[i] then PostMessage(hwnd(listbox1.Items[i]), WM_KEYDOWN, 入力キー名, 0); end; こんな感じで投げられるかな?と思ったのですが、悲しいほど無反応。 なにか根本的にやり方を間違えているのでしょうか・・・?

  • Delphi6 ループ中にキー入力

    Delphi 6 です。 for next などのループの中で、stringgridのセルをEnterキーで選択させたい時、選択されるまで(キーが押されるまで)処理を進めたくない方法は、どうするんでしょうか? flg:=false; for i:=1 to 100 do begin ~諸々の処理で flg:=true; ~ if flg=true then x[i]:= stringgridの選択されたRow番号(はじめからフォーカスされている番号でなく) ~諸々の処理で flg:=false; ~ end;

  • Delphi for文

    これって、Delphiのバグですか?特性ですか? procedure TForm1.Button1Click(Sender: TObject); begin test(); end; //-------------------------- procedure TForm1.test(); var k,x:integer; begin paintbox1.Canvas.pen.Color:=clBlack ; x:=0; for k:=1 to 3 do begin paintbox1.Canvas.moveto(x,0); paintbox1.Canvas.lineto(x,paintbox1.Height); x:=x+2; end; end; forループ内にブレークポイントを付けて「k」の値の変化を見ると、3,2,1と逆順になります。 「x:=x+2」を「x:=x+k」に変更すると、1,2,3と普通の順になります。 なぜ、こうなるのか? 対処法はありますか? Delphi Ver6・ターボDelphi どちらも同じ状況です。

  • DELPHI

    質問させてください。 WEBでサンプルプログラムを見ていたら以下の以下のような ソースがありました。 ----------- 省略 ----------- While not DM.bDeActive do begin ; End; ----------- 省略 ----------- DM.bDeActiveは他のフォームが処理中ならという意味あいなのですが、 ループ内の";"の処理内容がわかりません。 ご存知の方、宜しくお願いいたします。

  • Delphi のTComboBoxについて

    DelphiのTComboBoxについて質問があります。 SQLを走らせて検索結果をTComboBoxに格納しようと考えています。 例えばTComboBoxのNameをTCMBとしたとして -------------------------------- SQL発行 while 検索データEOF do begin TCMB.add(検索結果); 次のデータ見る(Fetch); end; -------------------------------- と上記のようになります。 しかし検索結果が同じデータがあった場合もTComboBoxに格納してしまいます。 TComboBoxには重複データを格納したくありません。 そこでいい方法というかTComboBoxの特徴(プロパティやらメソッドやら)あります でしょうか? ちなみにSQLはDISTINCTなどは使えず常に同じものを取得するようになっています。

  • ”ListBoxへのAddでエラー”

    タイトルの通りです。 DoubleからStringの型変換が不可なんでしょうか? ”.ToString” によってエラーになってるようです。 For~Eachでの3行で処理するとOKなのですが1行で なんとかならないものかと調べていましたが、いきずまっています。 Items.AddではなくItems.AddRangeを使う場合、どういうふうに 書くんでしょうか?。ちなみに、配列がString型の場合にはエラー にならないことは知っています。(.ToStringも不要) ’--------サンプル---------- Public Class Form1 Private Sub Button1_Click() Handles Button1.Click Dim Test_arr() As Double = {1.4, 1.2, 1.9, 1.7, 1.4, 2.8, 1.2, 3.2, 1.99, 4.2} ListBox1.Items.AddRange(Test_arr.ToString) '←この行でエラー For Each x As Double In Test_arr '←これはOK ListBox1.Items.Add(x.ToString) ' Next ' End Sub End Class エラー内容は、↓ ------------------------------------------------------------------ エラー 1 これらの引数で呼び出される、アクセス可能な 'AddRange' が ないため、オーバーロードの解決に失敗しました: 'Public Sub AddRange(items() As Object)': 型 'String' の値を 'Object の 1 次元配列' に変換できません。 'Public Sub AddRange(value As System.Windows.Forms.ListBox.ObjectCollection)': 型 'String' の 値を 'System.Windows.Forms.ListBox.ObjectCollection' に変換できません。 ------------------------------------------------------------------ どなたかご教授願えれば幸いです。環境はVisualBasic2010+WindowsXPです。

  • Delphiのマルチスレッドの割り込み処理について

    Delphiのマルチスレッドの割り込み処理について教えて欲しいのですが、ファイルをスレッドオブジェクトで作成して クラス名.Execute関数内でSynchronizeメソッドを使用しています。 本にはSynchronizeメソッドは「渡したメソッドが実行され終了するまで待ちます」と書いてあり、テストプログラムを作成してもそうでした。ということはSynchronizeメソッドは普通の関数と一緒のような気がしてしまうのですが、違うのでしょうか? Procedure MyThread.Execute begin Synchronize(AAA); AAAの処理が終了するまで待機している end; Procedure TmyThread.AAA; begin 'したい処理' end;

  • リストボックスのアイテムをマウスで並べ替えたいです

    リストボックスのアイテムをマウスのドラッグドロップで並べ替えたいのですが、 下のような感じで書いてみたのですが、 この状態だと、4番目のものを一番上に持ってくるという動作だけするのですが、 4番目から3番目に移動する場合や、1番目から3番目に移動する場合など 追加していくとIFが重なってきてすごくややこしくなってしまいます。 もっと分かりやすくて合理的な方法がありましたら、 大体でも良いですので、教えて頂けたら助かります。 よろしくおねがいいたします。 Private Sub Form1_Load(...略 ListBox1.Items.Add("AAA") ListBox1.Items.Add("BBB") ListBox1.Items.Add("CCC") ListBox1.Items.Add("EEE") End Sub Private Sub ListBox1_MouseDown(...略 SelectedSortFrom = ListBox1.SelectedIndex End Sub Private Sub ListBox1_MouseUp(...略 SelectedSortTo = ListBox1.SelectedIndex ListBox1Sort(SelectedSortFrom, SelectedSortTo) End Sub Private Function ListBox1Sort(ByVal From As Integer, ByVal Too As Integer) If From = -1 Then Exit Function If Too = -1 Then Exit Function Dim A(ListBox1.Items.Count) As String Dim B As Boolean For i As Integer = 0 To ListBox1.Items.Count - 1 A(i) = ListBox1.Items(i) Next For i As Integer = 0 To ListBox1.Items.Count - 1 If i = Too Then ListBox1.Items(i) = A(From) B = True Else ListBox1.Items(i) = A(i - 1) End If Next End Function

  • FirebirdへのDelphiによるデータ入力

    Deldhi2010とFirebird2.5を使っています。 下記のコードでデータを入力しているのですが、実行中の他のプログラムで入力済みのデータが見えません。また、二つのPCで入力していくとTest_Noが二重に登録されます。入力したデータがデータベースに反映されていないように見えます。しかし、表示コードにもトランザクションを適応すると問題は解決しますが、理由がわかりません。ご指導よろしくお願いいたします。 (入力コード) procedure TForm.ButtonRegClick(Sender: TObject); var I:Integer; begin if not TIBTransaction.InTransaction then IBTransaction.StartTransaction; try with TIBQuery do begin Close; SQL.Clear; SQL.Add('select max(Test_No) from TESTDB'); Open; I:=FieldByName('max').AsInteger; // Close; SQL.Clear; SQL.Add('insert into TESTDB (Test_No,TempText) values (:TN,:TT)'); ParamByName('TN').AsInteger:=I+1; ParamByName('TT').AsString:='Test'; ExecSQL; end; IBTransaction.Commit; except IBTransaction.Rollback; ShowMessage('Reg Error !!'); end; (表示コード) with TStringGrid do begin RowCount:=1; Rows[0].Clear; end; with TIBQuery do begin Close; SQL.Clear; SQL.Add('select * from TESTDB order by Test_No'); Open; I:=0; First; while not Eof do begin inc(I); TStringGrid.RowCount:=I; TStringGrid.Cells[0,I-1]:=IntToStr(FieldByName('Test_No').AsInteger); TStringGrid.Cells[1,I-1]:=FieldByName('TempText').AsString; Next; end; end;

  • VB2010でCOM番号をListBoxに格納する

    VB2010でシリアルポート番号をListBoxに格納するには コードは以下になります。現時点でListBoxに何も表示されません。 Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load End Sub Private Sub GetSerialPortNames() ' Show all available COM ports. For Each sp As String In My.Computer.Ports.SerialPortNames ListBox1.Items.Add(sp) Next End Sub End Class 上記コードは下記URLを参考しています。 「Visual Basic で利用可能なシリアル ポートを表示する」 http://msdn.microsoft.com/ja-jp/library/9wahf8t8%28v=vs.80%29.aspx 素人ですが、どこが足りないのは教えて下さい。