Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.06.29;
Скачать: CL | DM;

Вниз

отображение 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;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.027 c
9-1106052894
_Дельфин_
2005-01-18 15:54
2005.06.29
Помогите найти DirectX


14-1117612604
Тульский
2005-06-01 11:56
2005.06.29
Мирный договор с Японией


14-1117599792
12DFBDDh
2005-06-01 08:23
2005.06.29
Техничесоке задание


14-1117276248
BigMac
2005-05-28 14:30
2005.06.29
Задача по физике


14-1117863334
Гость4
2005-06-04 09:35
2005.06.29
Россия-Латвия