2015-10-24 17 views
2

我有一個綁定到FDConnection的FDQuery。FireDac FDQuery提交在瀏覽結果時更改了DataFields

我在帶有DB數據感知組件的表單上顯示數據。

每當我使用FPQuery.Next,.Prior,...它在結果之間瀏覽。

一切工作正常。

除了當我改變一個值(例如約翰 - >簡),然後使用FPQuery.Next獲取下一個結果時,它保存提交更改值到數據庫即使我沒有FDQuery1.CommitUpdates。

當用戶按下nbPost-Button或使用FDQuery1.CommitUpdates而不是在瀏覽結果之間時,有沒有辦法只保存更改的DataField?

enter image description here

謝謝!

+1

默認情況下,德爾福TDataSets移動之前發佈到當前行的任何變化數據集光標移動到另一行,如.Next或.Prior。標準的TDBNavigator Post按鈕只能調用DataSet.Post,並且不會自己提交對後端數據庫的更改。你想在數據集滾動之前推遲提交更改或取消更改?換句話說,當用戶從未保存/未提交更改的行中滾動時,您希望應用程序如何響應? – MartynA

+0

感謝MartynA。當用戶滾動到下一個/之前的數據時,我想丟棄未保存/未完成的更改。我只想在用戶按下綠色勾號時保存它們。 – Tommy

回答

2

就像我在評論中所說的,標準TDataset的行爲是調用其.Post方法在導航到另一行之前保存對當前行的更改。這發生在例程TDataSet.CheckBrowseModeData.DB.Pas中,在任何導航操作之前調用該例程。如果不派生自定義的TDataset後代,這是不能改變的。

(從Data.DB.Pas)

procedure TDataSet.CheckBrowseMode; 
begin 
    CheckActive; 
    DataEvent(deCheckBrowseMode, 0); 
    case State of 
    dsEdit, dsInsert: 
     begin 
     UpdateRecord; 
     if Modified then Post else Cancel; 
     end; 
    dsSetKey: 
     Post; 
    end; 
end; 

當然,一個TDataSetBeforePost事件,所以它可能是很有誘惑力的嘗試,並用它來取消更改;然而,BeforePost的問題是如何確定被調用的上下文,以便能夠判斷是否從CheckBrowseMode調用它,而不是用戶單擊保存按鈕的結果。

圍繞着簡單的方式是趕BeforeAction事件您DBNavigator的,它會調用數據集上的導航作用,這將觸發.Post前:

procedure TForm1.DBNavigator1BeforeAction(Sender: TObject; Button: 
    TNavigateBtn); 
var 
    Res : Integer; 
    DataSet : TDataSet; 
begin 
    DataSet := DBNavigator1.DataSource.DataSet; 
    case Button of 
    nbFirst, 
    nbPrior, 
    nbNext, 
    nbLast: begin 
     if DataSet.State in [dsEdit, dsInsert] then begin 
     Res := MessageDlg('The current row has unsaved changes. Abandon them?', mtWarning, [mbYes, mbNo], 0); 
     if Res = mrYes then 
      DataSet.Cancel 
     else 
      DataSet.Post; 
     end; 
    end; 
    end; 
end; 
1

很好的回答MartynA。

如果您不想在導航組件限制,並有一般這樣的檢查可以覆蓋TFDQuery.InternalPost像這樣:

procedure TFDQuery.InternalPost; 
begin 
    if State in [dsEdit, dsInsert] then 
    begin 
    if MessageDlg('Save changes?', mtWarning, [mbYes, mbNo], 0) = mrNo then 
     Cancel(); 
    end; 

    inherited; 
end; 
+0

謝謝,但正如我在我的回答中所說的,「全面檢查」檢查的問題是確定檢查被調用的上下文。我認爲,如果用戶每次進行明確的保存(例如,通過點擊DNav的保存按鈕),他們都有權被激怒,他們會被要求確認。無論如何,OP顯然會自動發佈發佈的想法,除非您採取措施避免它。 – MartynA