Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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.04 c
9-1111239509
Radgar
2005-03-19 16:38
2005.06.29
Как изменить разрешение монитора.


1-1117611609
Стас
2005-06-01 11:40
2005.06.29
Что за компонент?


1-1117867534
Vf
2005-06-04 10:45
2005.06.29
массив


9-1111763616
qwe
2005-03-25 18:13
2005.06.29
GLScene врашение объекта


14-1115242958
i-s-v
2005-05-05 01:42
2005.06.29
SMS





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский