Форум: "Базы";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];
Внизотображение Hint у DBGrid Найти похожие ветки
← →
Lex_! © (2005-05-11 13:21) [0]Попытка номер два.....
Имееться DBGrid с одним видимым полем (полей всего три)
Требуется: при наведении мышки на DBGrid на конкретное значение в столбце вывести хинт где указано то что находиться в другом поле (в неотображенном)
тоесть: есть запись содержащая -
текстполя1 текстполя2(не отображается
при наведении на текстполя1 в хинте показать надпись "текстполя2"
← →
Johnmen © (2005-05-11 13:36) [1]А что именно интересует? Показ хинта или показ др.поля?
← →
Virgo_Style © (2005-05-11 13:46) [2]Кажется, проблема тут в соответствии "координата мыши - запись в DataSet". Я в свое время решения не нашел...
← →
sniknik © (2005-05-11 13:59) [3]Virgo_Style © (11.05.05 13:46) [2]
серьезно?
это же очень просто
var
Point: TPoint;
GridCoord: TGridCoord;
begin
Point:= DBGrid1.ScreenToClient(Mouse.CursorPos);
GridCoord:= DBGrid1.MouseCoord(Point.X, Point.Y);
GridCoord.X - //это колонка
GridCoord.Y - //это строка (вроде бы ;о)), проверь)
координаты в гриде нашли, в датасете y должен соответствовать значению поля DataLink.Fields[y] (опять вроде бы ;о)), сам этого не делал...). все, вот и все соответствие (надо только проверить ;о), мне это было без надобности).
← →
Lex_! © (2005-05-11 14:10) [4]
> А что именно интересует? Показ хинта или показ др.поля?
Показ в хинте другого поля.
Надо в общем по положению курсора в гриде перейти на запись в таблице которая на данный момент отображается в гриде, и показать одно из полей записи в хинте
> координаты в гриде нашли, в датасете y должен соответствовать
> значению поля DataLink.Fields[y] (опять вроде бы ;о)), сам
> этого не делал...). все, вот и все соответствие (надо только
> проверить ;о), мне это было без надобности).
Это место подробнее можно?.
тоесть как перейти на запись в датасете (лучше в таблице) на ту на которой расположена мыш в данный момент
← →
Johnmen © (2005-05-11 14:17) [5]>Надо в общем по положению курсора в гриде перейти на запись
Не надо. Есть буфер отображаемых записей. Из него и тянуть...
Идеальный пример кода, как это сделать, см. в исходниках TDBGridEh из библиотеки EhLib.
← →
sniknik © (2005-05-11 14:17) [6]> Это место подробнее можно?.
вообщето это я не подумав ляпнул. ;о)) DataLink.Fields это скорее всего поля в текущей записи а не номера записей...
тебе придется скорее всего сохранять хинты для каждой отображаемой в гриде записи (менять в списке можно по отрисовке там все одно на каждую запись свое событие). т.е. сделать масив записей по числу строк в гриде... и т.д. пробуй.
← →
Virgo_Style © (2005-05-11 14:22) [7]sniknik © (11.05.05 13:59) [3]
Как бы не наврать... Но по-моему, проверить все же надо было ;-)
Насколько я помню свои неудачные попытки, X и Y получаются без учета скроллинга, то есть, это номера записей отображаемых, а не действительных.
Впрочем, мне это тоже давно без надобности :o)
← →
Lex_! © (2005-05-11 14:33) [8]
> Johnmen © (11.05.05 14:17) [5]
> >Надо в общем по положению курсора в гриде перейти на запись
>
>
> Не надо. Есть буфер отображаемых записей. Из него и тянуть...
> Идеальный пример кода, как это сделать, см. в исходниках
> TDBGridEh из библиотеки EhLib.
А в буфере есть поля записи которые не определены вообще в гриде?... у меня там написано одно поле и все..
← →
sniknik © (2005-05-11 14:36) [9]> это номера записей отображаемых, а не действительных.
истинно так, с гриде вообше всего столько строк сколько видно(иногда на одну больше, это я чегото проверял, сталкивался) а не по числу записей в рекордсете (как многие почемуто думают). поэтому и будет первая запись в гриде показывать 1(/0) а не 148-ю от начала рекордсета. но соответствие проставить всетаки можно, начало откуда грид рисует в самом гриде и запоминается.
было бы зачем. ;о) (както незаметно и давно уже отошол от понятий какие в striggrid трактуются, и както странно так стало, то, что тогда важным считал сейчас совсем не нужно...)
← →
КиТаЯц © (2005-05-11 14:38) [10]Ну и мне как-то без надобности... Дай-ка тоже ляпну не подумавши... ;)
Имеем Х и У без учета скролинга. Надо с учетом скролинга. Если я не ошибаюсь то текущая запись ДатаСета в гриде всегда на экране... Далее надо получить что-то вроде кординат текущей записи и потом:
Х (У) искомое := Х (У) записи под мышью/высоту строк Грида - (У) записи текущей...
Может кто разовьет тему?
← →
sniknik © (2005-05-11 14:41) [11]> А в буфере есть поля записи которые не определены вообще в гриде?... у меня там написано одно поле и все..
ну так делай этот буфер/массив сам, и сохраняй в него то что тебе нужно.
кстати не встречал чтото такого буфера, это только TDBGridEh есть или в стандартном гриде тоже? (нестандартные компонентами у нас запрещено использовать, что надо пиши сам, поэтому EhLib-а не имею)
← →
sniknik © (2005-05-11 14:44) [12]> Может кто разовьет тему?
нафига? зачем чегото там высчитывать, что можно элементарно получить в событии на отрисовке поля (например) без всяки вычислений прямым копированием.
← →
Johnmen © (2005-05-11 14:48) [13]Есть сырцы со стандартным... Но очень сырые, но основной принцип поясняющие.
← →
sniknik © (2005-05-11 15:31) [14]> Есть сырцы со стандартным... Но очень сырые, но основной принцип поясняющие.
значит в стандартном всетаки нету, раз для него сырцы ктото для этого писал...
не, спасибо конечно, но я худо бедно способен и сам это реализовать. ;о)) просто думал чтото пропустил, есть буфер а я его не вижу...
← →
Johnmen © (2005-05-11 16:12) [15]>значит в стандартном всетаки нету, раз для него сырцы ктото для этого писал...
Да есть же. Просто в сырцах пример использования со смещением ActiveRecord"а в DataLink"е.
← →
sniknik © (2005-05-11 16:18) [16]значит пропустил... вышли тогда если не сложно.
← →
sniknik © (2005-05-11 16:29) [17]я вообще думал свой буфер сделать (если бы пришлось решать подобное)
ну типа
TMyDBGrid = class(TDBGrid)
Hints: array of string;
procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); override;
end;
Hints на onResize меняем размер, в DrawCell сощраняем нужную запись в буфер, ARow - номер строки (= позиции в буфере) есть, в событии копируем то что нам нужно(1 или несколько полей для нинта из текущего DataLink-а), вызываем родительскую перерисовку и все.
по onMouseMove смотрим позицию в гриде (как выше показывал) и если изменилась показываем hint.
в общем очень просто. так думаю ;о)) у тебя сложнее?
← →
Johnmen © (2005-05-11 16:42) [18]ок
← →
Johnmen © (2005-05-11 16:43) [19]ок - в смысле, выслал. Там всё достаточно несложно...
← →
sniknik © (2005-05-11 17:43) [20]Ok. (в смысле получил ;о))), действительно попроще, чем у меня бы получилось. и кода меньше.
а вот то что так можно активную запись менять, не знал (да и не стремился особо ;о), но может пригодиться).
код точно "конкретно" сырой ;о), на заголовке таблици вываливается с AV понятно почему выход за пределы, в отладчике естественно в проге видно не будет, но лучше бы и этого не допускать.
и еще, кстати, там всетаки обходится без буфера, т.к. если взять значение не из DataLink-а а напрямую из датасета то оно всетаки меняется, т.е. код сначала делает активной запись под мышью а после вертает "взад" (если бы был буфер этого бы не наблюдалось), делает это довольно часто (на каждое перемещение мыши) отчего заметно мерцание хинта и даже грида на перерисовке... в общем использовать в том виде что есть категорически запрещено. ;о))) ну дак, предупреждали...
← →
Lex_! © (2005-05-11 17:59) [21]А ето, мне тоже можно выслать?...
надо же как то это сделать ...
← →
Johnmen © (2005-05-11 18:08) [22]Так ведь даталинк фактически и есть буфер.
И значения надо брать из него...
← →
sniknik © (2005-05-11 18:27) [23]> Так ведь даталинк фактически и есть буфер.
ну тогда это буфер из букмарков, т.к. изменения позиции в нем ведут и к изменению позиции в рекордсете.
> А ето, мне тоже можно выслать?...
ну как Johnmen решит... если бы мой код был я решал ;о) высылать или нет, но все одно его там дорабатывать нужно (к примеру если просто проверку на смену позиции поставить и значение хинта на это время (время неизменности позиции) запоминать, то вполне можно избавиться от мерцания и в таком варианте, не так часто перерисовываться будет), а компонент переделывать (как я хотел) не придется.
← →
Polevi © (2005-05-12 09:51) [24]type
TGridHelper=class(TCustomDBGrid);
procedure TMainForm.ApplicationEvents1ShowHint(var HintStr: String;
var CanShow: Boolean; var HintInfo: THintInfo);
var
pt:TPoint;
gc:TGridCoord;
saveNo:Integer;
dl:TDataLink;
begin
GetCursorPos(pt);
pt:=Grid.ScreenToClient(pt);
gc:=Grid.MouseCoord(pt.X,pt.Y);
dl:=TGridHelper(HeadersGrid).DataLink;
saveNo:=dl.ActiveRecord;
try
dl.ActiveRecord:=gc.Y-1;
HintStr:=Grid.DataSource.Dataset["SomeField"];
finally
dl.ActiveRecord=saveNo
end;
end;
← →
Johnmen © (2005-05-12 10:05) [25]>sniknik © (11.05.05 18:27) [23]
>ну тогда это буфер из букмарков, т.к. изменения позиции в нем
>ведут и к изменению позиции в рекордсете.
Тот пример показывает, что не ведут. Проверил. Ещё в исходники слегка глянул...
← →
sniknik © (2005-05-12 11:06) [26]> Тот пример показывает, что не ведут. Проверил. Ещё в исходники слегка глянул...
ну не ведут так не ведут. ;о)) бессмысленный спор изз совершенно ненужного предмета...
просто обьясню с чего так решил
procedure TForm1.DBGrid1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
Grid : TDBGrid;
Cell : TGridCoord;
CellRect : TRect;
HintCol : TColumn;
OldActive : Integer;
Value : string;
Pt : TPoint;
begin;
Grid:= Sender as TDBGrid;
Cell:= Grid.MouseCoord(X,Y);
if (Cell.X<1) or (Cell.Y<0) then Exit;
try
HintCol:=Grid.Columns[Cell.X-1];
Value:="";
OldActive:= MyDBGrid(Grid).DataLink.ActiveRecord;
try
MyDBGrid(Grid).DataLink.ActiveRecord:= Cell.Y-1;
Value:= HintCol.Field.DisplayText;
CellRect:= MyDBGrid(Grid).CellRect(Cell.X,Cell.Y);
GetCursorPos(Pt);
CellRect:= FHintWindow.CalcHintRect(Grid.Width, Value, nil);
OffsetRect(CellRect, Pt.X, Pt.Y);
//FHintWindow.ActivateHint(CellRect, Value);
CellRect.Right:= CellRect.Right + 300;
FHintWindow.ActivateHint(CellRect, ADODataSet1SCHIM.AsString);
finally
MyDBGrid(Grid).DataLink.ActiveRecord:= OldActive;
Grid.Repaint;
end;
except
FHintWindow.ReleaseHandle;
end;
end;
закоментаренную строчку заменил двумя нижеследующими, в гриде определено 1 поле, показываю (ADODataSet1SCHIM) другое, которое есть только в датасете (и оно немного длиннее ;о), как понятно из кода).
так вот поле то только в рекордсете присутствует и берется не с даталинка а непосредственно с датасета, и тем не менее оно меняется при смене записи... т.е. налицо переход между записями. (но даже если опровергнеш. мне пофигу, чест.слово ;о)), пусть так и будет, копатся в этом буду только если действительно понадобится, в чем сомневаюсь ;)
ну вот, мимоходом целых 2 варианта выложили. ;о) если разберется, будес с чего начать.
← →
Johnmen © (2005-05-12 11:20) [27]>sniknik © (12.05.05 11:06) [26]
Я тоже ни о чём не спорю... И мне это не очень интересно...
Просто уточнение (возм.пригодится тем, кто захочет разобраться), надо см. DataLink.Fields[i] (естественно, найденный), а не непосредственно поле из НД.
← →
Bronco © (2005-05-12 11:47) [28]изменение ActiveRecord не ведут к изменению позиции в датасете.
вот совсем упрощенный вариант (вдруг автору пригодится)procedure TForm1.DBGrid1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var Coord:TGridCoord;
CurRec:Integer;
begin
with TMyDBGrid(DBGrid1) do
begin
Coord:=MouseCoord(x,y);
with Coord do
if (Y < 1) or (X < 1) or (X > Columns.Count) then Exit;
CurRec:=DataLink.ActiveRecord;
DataLink.ActiveRecord:=Coord.Y-1;
Label1.Caption := Columns[Coord.X].Field.AsString;
DataLink.ActiveRecord:=CurRec;
end;
end;
← →
sniknik © (2005-05-12 12:03) [29]опять я со своими глупостями ;о))
> изменение ActiveRecord не ведут к изменению позиции в датасете.
опять возьмем "левое" поле не определенное в гриде, только в рекордсете
procedure TForm1.DBGrid1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var Coord:TGridCoord;
CurRec:Integer;
begin
with TMyDBGrid(DBGrid1) do begin
Coord:=MouseCoord(x,y);
with Coord do
if (Y < 1) or (X < 1) or (X > Columns.Count) then Exit;
CurRec:=DataLink.ActiveRecord;
DataLink.ActiveRecord:=Coord.Y-1;
Label1.Caption:= //Columns[Coord.X-1].Field.AsString;
ADODataSet1SCHIM.AsString;
DataLink.ActiveRecord:=CurRec;
end;
end;
и видим саптион меняется! чего бы не происходило если бы в нем(датасете) не менялась позиция...
вывод: они меняются (она всетаки вертится! ;о))), вам этого просто не показывают.
p.p.s. на этот раз все, надоело. ;)
← →
Bronco © (2005-05-12 12:14) [30]
> sniknik © (12.05.05 12:03) [29]
ну да, естественно, значение поля меняется. Но позиция курсора в датасете - нет :-) Иначе нафиг нужны эти выкрутасы с Datalink, могли бы и обычными средствами навигации (MoveBy etc) обойтись
← →
Bronco © (2005-05-12 12:25) [31]и еще кстати, простой способ - навесить каких нибудь мастер-детальных связок и посмотреть. Полагаю что они даже не дернутся :-)
← →
sniknik © (2005-05-12 12:25) [32]> ну да, естественно, значение поля меняется. Но позиция курсора в датасете - нет :-)
ага, вижу, самому смешно стало, да?
> могли бы и обычными средствами навигации (MoveBy etc) обойтись
тогда сложно проставить соответствие строка в гриде - строка в датасете (номера не совпадают). попробуй.
← →
sniknik © (2005-05-12 12:26) [33]Bronco © (12.05.05 12:25) [31]
проверь. у меня обед. ;о))
← →
sniknik © (2005-05-12 12:27) [34]кстати не показатель, при отключеных контролах...
← →
Bronco © (2005-05-12 12:43) [35]
> sniknik © (12.05.05 12:26) [33]
Проверил. Так и есть :-)
Контролы НЕ отключены, а связка даже не дергается. Мало того, другие DB контролы на форме также не дергаются.
Отсюда вывод - позиция курсора - не меняется.
← →
Lex_! © (2005-05-15 12:52) [36]и в итоге?... можно или нет чтотт сделать то?:)
← →
sniknik © (2005-05-15 13:44) [37]> и в итоге?... можно или нет чтотт сделать то?:)
а сам то как думаеш? после приведенных 3 вариантов одного метода, и словами описаного другого, еще не логадываешся?
Bronco © (12.05.05 12:43) [35]
> Отсюда вывод - позиция курсора - не меняется.
сорри просмотрел... ну да продолжим. сегодня как раз выходной, скучно.
береш свой вариант [28]
коментируеш строку //DataLink.ActiveRecord:=CurRec; (зачем восстанавливать, если позиция не меняется?)
дальше ставиш позицию клавишами на 1 (к примеру), заводиш мышу на середину позиций грида и нажимаеш кнопку "вниз". откуда началось скролирование? выводы делай сам.
а связка не дергается потому что смена идет в навигационных методах Next, Pred, ... т.д. контролы отключать нет надобности, если используется метод "до них", более низкоуровневый.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.045 c