レコードの挿入で一番上の行が選択されてしまう - umemura - 05-24-2013
レコードの挿入をするために、インデックスをつけて、選択されている行に追加したレコードが表示されるようにソートしています。
しかし、なぜか、レコードの一番上の行が選択されてしまいます。
batch-events? を利用しないと、現在の選択はそのままとなるのですが、
それだと、レコードの追加に時間がかかってしまいます。
現在のレコードの選択状態を変えないままレコードを挿入するには
どうすればよいでしょうか。
Code: {let rs:RecordSet =
{RecordSet
{RecordFields
{RecordField "index", domain = int},
{RecordField "First", domain = String},
{RecordField "Last", domain = String},
{RecordField "Age", domain = int}
}
}
}
{for i:int = 0 to 100 do
def rd = {RecordData}
set rd["index"] = i + 1
{rs.append rd}
}
{def grid =
{RecordGrid
sort = "index",
record-source = rs
}
}
{value grid}
{CommandButton
{on Action do
let insert-index:int = rs.size
{if grid.current-index > -1 then
set insert-index = grid.current-index + 1
}
def new-r = {RecordData}|| {rs.new-record}
set new-r["index"] = insert-index
||batch-events? を使うと一番上のレコードが選択されてしまう
{with rs.batch-events? = true do
||挿入のために、対象インデックス以降を+1
{for r in rs do
{if r["index"] asa int >= insert-index then
set r["index"] = r["index"] asa int + 1
}
}
}
{rs.append new-r}
||下記コードで、元の選択状態に戻せるが
||画面がちらついたり、スクロール位置が変わるのが問題
||++ {after 0s do
||++ {grid.select-record insert-index}
||++ set grid.current-index = insert-index
||++ }
}
}
RE: レコードの挿入で一番上の行が選択されてしまう - Yuhki - 05-27-2013
RecordGridに以下を設定してみてください。
key-spec = RecordSetDisplay.preserve-indices
RE: レコードの挿入で一番上の行が選択されてしまう - umemura - 05-27-2013
ヘルプを見ると、 「既存のインデックスおよび選択したものを保存する」とありますね。
私の望む振る舞いをしてくれました。
ありがとうございます。
Code: {curl 8.0 applet}
{curl-file-attributes character-encoding = "utf8"}
{applet manifest = "manifest.mcurl",
{compiler-directives careful? = true}
}
{let people:RecordSet =
{RecordSet
{RecordFields
{RecordField "index", caption = "No.", domain = int},
{RecordField "First", domain = String},
{RecordField "Last", domain = String},
{RecordField "Age", domain = int}
}
}
}
{for i:int = 0 to 10 do
{people.append {RecordData index = i + 1, Age = i + 1}}
}
{define-class public SortrderGrid {inherits RecordGrid}
{constructor public {default
record-source:#RecordSet = null,
...}
{construct-super {splice ...}}
set self.record-source = record-source
}
||グリッドのヘッダークリックでソートしたときには
||RecordSet からはこのイベントは発生しないため、
||継承したグリッドの sort セッターで無理やり発生させている
{setter public {sort sort:#RecordSort}:void
{if-non-null rs = self.record-source then
{rs.handle-event {RecordsReordered}}
}
set super.sort = sort
}
{setter public {record-source rs:#RecordSet}:void
set super.record-source = rs
{if-non-null rs = self.record-source then
{rs.add-event-handler
{on e:RecordsChanged at rs:RecordSet do
{type-switch e
case ra:RecordAdded do
def insert-index = self.current-index + 1
{with rs.batch-events? = true do
{for idx:int = rs.size above 0 do
{if insert-index <= idx then
{if-non-null select-record =
{rs.select-one
filter = {RecordFilter
{proc {r:Record}:bool
{if r["index"] asa int == idx then
{return true}
else
{return false}
}
}
}
} then
set select-record["index"] = idx + 1
}
}
}
set ra.record["index"] = insert-index
{if-non-null sort = self.sort then
set super.sort = {RecordSort.concat sort, {RecordSort.from-string "index"}}
}
}
{return}
case ra:RecordModified do
case rr:RecordRemoved do
case ro:RecordsReordered do
case rbc:RecordsBulkChanges do
else
{return}
}
{after 0s do
{with
self.records.batch-events? = true ,
rs.batch-events? = true do
{for r key idx:int in self.records do
set r["index"] = idx + 1
}
}
}
{return}
}
}
{rs.handle-event {RecordsReordered }}
}
}
}
{def grid =
{SortrderGrid
||レコードの選択行が移動してしまう問題の対応
key-spec = RecordSetDisplay.preserve-indices,
record-source = people,
height = 5in,
width = 5in
}
}
{CommandButton
label = "挿入",
{on Action do
{if-non-null rs = grid.record-source then
{rs.append {RecordData}}
}
}
}
{CommandButton
label = "削除",
{on Action do
{if-non-null r = grid.current-record then
{r.delete}
}
}
}
{value grid}
RE: レコードの挿入で一番上の行が選択されてしまう - umemura - 10-28-2013
batch-event?=true の状態で最初のレコードを append する際には、
key-spec = RecordSetDisplay.preserve-indices を指定していても、
select-current-record? = true である以上は、
必ず一番上のレコードが選択されてしまう、という認識ですが、この認識はあっていますか?
回避策は、レコードの追加処理の前に select-current-record? をfalse にして、
追加処理の後に イベントのディスパッチをしたうえで、
select-current-record? を true に戻す、という方法がありそうですが、
できれば、dispatch-events を使いたくありません。
これ以外の方法はありませんか?
Code: {CommandButton
label = "レコード追加",
{on Action do
set rg.select-current-record? = false
{with rs.batch-events? = true do
{for i:int = 0 to 10 do
def new-r = {rs.new-record}
{rs.append new-r}
}
}
{dispatch-events false}
set rg.select-current-record? = true
}
}
RE: レコードの挿入で一番上の行が選択されてしまう - umemura - 09-19-2014
key-spec = RecordSetDisplay.preserve-indices の設定さえしてあれば、
グリッド内のレコードを、いったんクリア(delete-all)して、
新しいレコードをセットするという一連の処理を with RecordSet.batch-events?=true の中で行うことで、
グリッドのスクロール位置や、選択レコードをそのままの状態にしておけますね。
入力画面などで、DBにいったん登録した後、自動で再検索をおこなうことが多いのですが、
スクロール位置や選択レコードがクリアされてしまうと、
さっきまで修正していたレコードがどれかわからなくなってしまうため、
このやり方でなら状態を保持でき、望ましい振る舞いになりました。
Code: {def rf-ary = {{Array-of RecordField}}}
{for i:int = 1 to 10 do
{rf-ary.append {RecordField {String i}, nullable? = true}}
}
{def rs = {RecordSet {RecordFields {splice rf-ary}}}}
{def grid = {RecordGrid
width =5in, height = 3in
,key-spec = RecordSetDisplay.preserve-indices
, record-source = rs
,select-current-record? = true
}}
{value grid}
{CommandButton
label = "レコード選択位置が変わらない",
{on Action do
{with rs.batch-events? = true do
{rs.delete-all}
{for i:int = 1 to 100 do
def new-r = {rs.new-record}
{for rf in rs.fields do
set new-r[rf.name] = {String i}
}
{rs.append new-r}
}
{rs.commit}
}
}
}
{CommandButton
label = "レコード選択位置が一番上になる",
{on Action do
{rs.delete-all}
{with rs.batch-events? = true do
{for i:int = 1 to 100 do
def new-r = {rs.new-record}
{for rf in rs.fields do
set new-r[rf.name] = {String i}
}
{rs.append new-r}
}
{rs.commit}
}
}
}
|