2016-04-19 2 views
3

У меня есть сетка записей, которую пользователь нажмет на мультивыбор для процесса. Некоторые из записей будут недействительными в зависимости от значений первой выбранной строки.DBGrid: как предотвратить выбор строки?

Я знаю о DBGrid.SelectedRows.CurrentRowSelected, но я не могу найти подходящее место для проверки моих условий, чтобы установить его в True или False.

Что-то вроде этого:

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; 

Я попытался OnMouseDown события в Application.OnMessage и в DBGrid и форме, но они не работают, и нет TBookmarkList.BeforeInsertItem события. Что я могу сделать или изменить?

+0

Ваш Q в, кажется, не соответствует тому, что вы описали в тексте д. Вы пытаетесь запретить пользователю выбирать некоторые строки в сетке? Если это так, почему бы просто не предотвратить их отображение в первую очередь, например. используя фильтр в наборе данных сетки? –

+0

Первая часть: да. Во-вторых, потому что пользователю нужно видеть данные, а затем решать, что выбрать, а не раньше ... Я сделал всю тему фильтра, которую вы можете себе представить, но я не могу изменить требования пользователя. –

+0

Как только пользователь сделал первый выбор (который является точкой, которую вы хотите отключить * строк), вы можете фильтровать, чтобы удалить неприемлемые строки, что намного чище с точки зрения пользовательского интерфейса. Хотя вы можете взломать таким образом, чтобы пользователь не мог выбирать определенные строки, в этот момент вы не можете рисовать их по-разному, указав, что они отключены (не выбираются). –

ответ

1

я бы не сделать его настолько сложным.
Если сравнение всегда выполняется при первом выборе.
Код, который я использую здесь, имеет твердое значение.
Не прыгайте в закладки.

// 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; 

Мы можем видеть два выбраны так
ShowMessage(IntToStr(DBGrid1.SelectedRows.Count));

показывает

enter image description here

Теперь мы хотим выбрать линию

Sportlich, ELEGANTE GUCCI Sonnenbrille

Мы знаем простой Pos() Sonnenbrille найти SONNENBRILLE Pos() будет = 0, поэтому выбор воли не состоится.

enter image description here

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

показывает слишком

КОД: Название

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

Я уже сократил жир Bookmark. Но события DBGRid KeyUP и MouseUP были ключом к тому, что я хотел. Большое спасибо. –

+0

@ JoséEduardo: Рад, что я мог бы помочь :-) –

2

Если вы посмотрите на источник TCustomDBGrid.MouseDown, вы увидите, как это работает, какая строка набора данных (если есть) произошла событие Mousedown. Вы также увидите линию, которая приводит к состоянию выбора текущей строки быть переключены:

if ssCtrl in Shift then 
    CurrentRowSelected := not CurrentRowSelected 

Имея это в виду, создать OnMouseUp событие для вашей сетки и поставить точку останова в нем.

Затем вы должны заметить, что из-за того, что происходит в MouseDown случае сетки, в к тому времени, OnMouseUp события называется, текущая строка набора данных сетки в переместилась к щелкнули DataRow (смотрите примечание ниже). Итак, в этот момент вы можете проверить, соответствует ли текущая строка критериям, по которым вы хотите разрешить пользователю выбирать его, и отменить выбор, если это не так. Я думаю, что ответы на ваши конкретные «как предотвратить выбор строки?»

Как пользователь, который отменял бы поведение, меня несколько раздражало бы, поэтому вы должны, вероятно, дать пользователю некоторое представление о том, почему строка была отменена.

Примечание: Очевидно, тот факт, что сетка-х Mousedown приведет к вызову набора данных MoveBy означает, что OnScroll события набора данных было уволен. В зависимости от того, что вы хотите сделать, событие OnScroll может быть местом, где можно проверить, соответствует ли текущий datarow вашим критериям выбора, и если это не так, начните процесс его отмены. В любом случае тот факт, что набор данных должен быть уже на datarow, где был вызван событие DBGrid.MouseDown, должен сэкономить вам проблемы с его идентификацией в вашем MouseUp.

Надеется, что будет достаточно, чтобы ты ...

Смежные вопросы