2016-04-19 17 views
3

Ich habe ein Raster von Einträgen, auf die der Benutzer klicken wird, um einen Prozess mehrfach auszuwählen. Einige der Einträge sind basierend auf den Werten der ersten ausgewählten Zeile ungültig.DBGrid: Wie kann verhindert werden, dass eine Zeile ausgewählt wird?

Ich weiß über DBGrid.SelectedRows.CurrentRowSelected, aber ich kann keinen geeigneten Platz zum Überprüfen meiner Bedingungen finden, um es auf True oder False setzen.

Etwas wie folgt aus:

var 
    bm: TBookmark; 
    CachedIdentity: String; 
    CanSelect: Boolean; 
begin 
    with dgbSkypeConversations do 
    begin 
    if SelectedRows.Count > 0 then 
    begin 
     DataSource.DataSet.DisableControls; 
     bm := DataSource.DataSet.GetBookmark; 
     CachedIdentity := DataSource.DataSet.FieldByName('identity').AsString; 
     DataSource.DataSet.GotoBookmark(SelectedRows[0]); 
     CanSelect := DataSource.DataSet.FieldByName('identity').AsString <> CachedIdentity; 
     DataSource.DataSet.GotoBookmark(bm); 
     DataSource.DataSet.FreeBookmark(bm); 
     SelectedRows.CurrentRowSelected := CanSelect; 
     DataSource.DataSet.EnableControls; 
    end; 
    end 
end; 

Ich habe versucht, die OnMouseDown Ereignisse in Application.OnMessage und des DBGrid und die Form, aber sie funktionieren nicht, und es gibt keine TBookmarkList.BeforeInsertItem Ereignis. Was kann ich tun oder muss ich ändern?

+0

TITEL q ist nicht zu passen scheint, was Sie in den Text des q beschreiben. Möchten Sie verhindern, dass der Benutzer einige Zeilen im Raster auswählt? Wenn dies der Fall ist, warum verhindern sie nicht, dass sie an erster Stelle angezeigt werden, z. indem Sie einen Filter im Dataset des Rasters verwenden? –

+0

Erster Teil: ja. Zweitens, weil der Benutzer die Daten sehen und dann entscheiden muss, was zu wählen ist, nicht vorher ... Ich habe die ganze Filtersache gemacht, die Sie sich vorstellen können, aber ich kann die Benutzeranforderung nicht ändern –

+0

Sobald der Benutzer die erste Auswahl getroffen hat (Dies ist der Punkt, den Sie * Zeilen * deaktivieren möchten. Sie können filtern, um die nicht zulässigen Zeilen zu entfernen, was vom Standpunkt der Benutzeroberfläche aus wesentlich sauberer ist. Während Sie so hacken können, dass der Benutzer bestimmte Zeilen nicht auswählen kann, können Sie sie an dieser Stelle nicht anders zeichnen, um anzuzeigen, dass sie deaktiviert sind (nicht auswählbar). –

Antwort

1

Ich würde es nicht so kompliziert.
Wenn der Vergleich immer bei der ersten Auswahl stattfindet.
Der Code, den ich hier verwende, hat einen fest codierten Wert.
Kein Sprung zu den Lesezeichen.

// first selection----------------------------- 
if DBGrid1.SelectedRows.Count = 1 then begin 
    CachedIdentity := 'Sonnenbrille'; // Sunglasses 
//CachedIdentity := DataSource.DataSet.FieldByName('identity').AsString; 
    Exit; 
end; 

Sie den Vergleich

if DBGrid1.SelectedRows.CurrentRowSelected then begin 
//if CachedIdentity <> DataSource.DataSet.FieldByName('identity').AsString 
    if Pos(LookingFor,DBGrid1.DataSource.DataSet.FieldByName('haupttxt').AsString)=0 
    then DBGrid1.SelectedRows.CurrentRowSelected := False; 
    ShowMessage(IntToStr(DBGrid1.SelectedRows.Count)); 
end; 

Wir zwei sind sehen, so
ShowMessage(IntToStr(DBGrid1.SelectedRows.Count));

zeigt

enter image description here

ausgewählt

Jetzt wollen wir die Linie

SPORTLICH, ELEGANTE GUCCI SONNENBRILLE

Wir wissen, einen einfachen Po() Sonnenbrille finden SONNENBRILLE Pos() zur Auswahl wird = 0, so eine Auswahl Willen nicht stattfinden.

enter image description here

ShowMessage(IntToStr(DBGrid1.SelectedRows.Count));

zeigt zu

Code:

var 
CachedIdentity : string; 

procedure TForm2.canSelectedV1; 
begin 
    // first selection----------------------------- 
if DBGrid1.SelectedRows.Count = 1 then begin 
    CachedIdentity := 'Sonnenbrille'; // Sunglasses 
//CachedIdentity := DataSource.DataSet.FieldByName('identity').AsString; 
    Exit; 
end; 
if DBGrid1.SelectedRows.CurrentRowSelected then 
begin 
//if CachedIdentity <> DataSource.DataSet.FieldByName('identity').AsString 
    if Pos(LookingFor,DBGrid1.DataSource.DataSet.FieldByName('haupttxt').AsString)=0 
    then DBGrid1.SelectedRows.CurrentRowSelected := False; 
    ShowMessage(IntToStr(DBGrid1.SelectedRows.Count)); 
end; 
end; 

procedure TForm2.DBGrid1MouseUp(Sender: TObject; Button: TMouseButton; 
    Shift: TShiftState; X, Y: Integer); 
begin 
canSelectedV1; 
end; 

procedure TForm2.DBGrid1KeyUp(Sender: TObject; var Key: Word; 
    Shift: TShiftState); 
begin 
canSelectedV1; 
end; 

end. 
+0

Ich hatte schon die Lesezeichen-Fettigkeit geschnitten. Aber die DBGRid KeyUP und MouseUP Ereignisse waren der Schlüssel zu dem, was ich wollte. Vielen Dank. –

+0

@ JoséEduardo: Ich bin froh, dass ich helfen konnte :-) –

2

Wenn Sie sich die Quelle von TCustomDBGrid.MouseDown ansehen, werden Sie sehen, wie die Datensatzreihe (falls vorhanden) des Mousedown-Ereignisses funktioniert. Sie sehen auch die Linie, die in den Auswahlzustand der aktuellen Zeile führt umgeschaltet werden:

if ssCtrl in Shift then 
    CurrentRowSelected := not CurrentRowSelected 

Mit dem im Verstand, ein OnMouseUp Ereignis für Ihren Grid einzurichten und einen Haltepunkt in ihr.

Sie sollten dann feststellen, dass aufgrund dessen, was in der MouseDown Veranstaltung Gitter geht weiter, durch die Zeit wird Ihr OnMouseUp Ereignis die aktuelle Zeile des Gitters des Datensatzes auf den geklickt datarow bewegt genannt hat (siehe Hinweis unten). An diesem Punkt können Sie überprüfen, ob die aktuelle Zeile die Kriterien erfüllt, nach denen Sie dem Benutzer die Auswahl ermöglichen sollen, und die Auswahl aufheben, wenn dies nicht der Fall ist. Ich denke, das beantwortet Ihr spezifisches "Wie verhindert man, dass eine Zeile ausgewählt wird?"

Als Benutzer, der das Verhalten abwählen würde mich etwas ärgern, so sollten Sie wahrscheinlich dem Benutzer einige Hinweise geben, warum die Zeile abgewählt wurde.

Hinweis: Offensichtlich ist die Tatsache, dass die Mousedown des Gitters in einem Aufruf der Datenmenge führt MoveBy bedeutet, dass die OnScroll Ereignis des Datensatzes wurde gefeuert. Je nachdem, was genau Sie tun möchten, kann das Ereignis OnScroll der Ort sein, an dem Sie überprüfen können, ob das aktuelle Datenarray Ihre Auswahlkriterien erfüllt, und falls dies nicht der Fall ist, beginnen Sie dort mit der Deaktivierung. In jedem Fall sollte die Tatsache, dass das Dataset bereits in dem Datarow sein sollte, in dem das Ereignis DBGrid.MouseDown aufgerufen wurde, Ihnen das Problem erschweren, es in Ihrem MouseUp zu identifizieren.

Hoffentlich genug sein wird, um Sie gehen ...

Verwandte Themen