ListView kolon tıklama

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Kullanıcı avatarı
brs
Üye
Mesajlar: 626
Kayıt: 04 Eki 2012 02:52

ListView kolon tıklama

Mesaj gönderen brs » 01 Haz 2014 07:25

Selam;

ListView de 1, 2 , 3, 4. kolan dışında herhangi bir alana tıkladığında uyarı verme istiyorum bunu nasıl yapabilirim...
aslında mantığı iki tarih alanında arama yapmak gibi bir şey fakat yapamadım

Kod: Tümünü seç

procedure TForm16.ListView1Click(Sender: TObject);
var
  iYeniItem, iYeniSubItem: Integer;
begin
 [b] if (XSubItem < 4) then[/b]
  begin
    ShowMessage('var');
  end
  else
  begin
    ShowMessage('Yok');
  end;
end;

İşi bilen yardım eder, az bilen akıl verir, bilmeyen eleştirir, yapamayan ise çamur atar...

xxxjedixxx
Üye
Mesajlar: 216
Kayıt: 10 Ara 2013 03:50

Re: ListView kolon tıklama

Mesaj gönderen xxxjedixxx » 01 Haz 2014 09:53

Anlattığından çok fazla bir şey anlamadım ama listview'da tıklanan noktalar hakkında bilgi alabileceğin bir örnek yazdım. İşine yarar mı bilmiyorum.

Örneği, Listview 'in RowSelect özelliği True ve False olarak iki türlü dene. Ben RowSelect'i True yaparak denedim, çalışyor.

Kod: Tümünü seç

procedure TForm1.ListView1Click(Sender: TObject);
var P: TPoint;
    HT: THittests;
begin
  GetCursorPos(P);
  Windows.ScreenToClient(ListView1.Handle, P);
  HT := ListView1.GetHitTestInfoAt(P.X, P.Y);
  if HT = [htNoWhere] then
    ShowMessage('Satırlar dışında bir yere tıklandı.')
  else if HT = [htOnItem] then
    ShowMessage('Satıra tıklandı.')
  else if HT = [htOnLabel] then
    ShowMessage('Etikete tıklandı.')
  else
    ShowMessage('Bir yere tıklandı ama pek anlamadım :)')
end;

Kullanıcı avatarı
brs
Üye
Mesajlar: 626
Kayıt: 04 Eki 2012 02:52

Re: ListView kolon tıklama

Mesaj gönderen brs » 01 Haz 2014 10:39

Üstat zaman ayırdığın için teşekkür ederim,

Windows.ScreenToClient(ListView1.Handle, P); satırında hata alıyorum?

Yapmak istediği özetle listview de yaklaşık 10 adet kolon var fakat 1.2.3.4. kolon dışında bir kolon tıkladığında kullanıcya uyarı vermek istiyorum...
İşi bilen yardım eder, az bilen akıl verir, bilmeyen eleştirir, yapamayan ise çamur atar...

xxxjedixxx
Üye
Mesajlar: 216
Kayıt: 10 Ara 2013 03:50

Re: ListView kolon tıklama

Mesaj gönderen xxxjedixxx » 01 Haz 2014 11:49

Delphi7 için windows yazılıyor. İleri sürümlerde Windows yerine Winapi.Windows olması lazım (uses kısmına bak).
Kodu çalıştır bir bak sonra subitems kısmını hesaplatarak bulursun. Tıklanan koordinatı, p.x ve p.y ile alacaksın. Burada sana p.x yetecek gibi.

Aşağıdaki gibi bir çalışma yapabilirsin. Denemeden yazıyorum fikir vermesi için.

songenislik := 0;
for i := 0 to 3 do
songenislik := songenislik + listview.columns.width;

if (p.x > listview.columns[0].width) and (p.x < son_genislik) then
senin alanına tıklanmıştır.
else
hata

Kullanıcı avatarı
brs
Üye
Mesajlar: 626
Kayıt: 04 Eki 2012 02:52

Re: ListView kolon tıklama

Mesaj gönderen brs » 02 Haz 2014 03:04

xxxjedixxx yazdı:Delphi7 için windows yazılıyor. İleri sürümlerde Windows yerine Winapi.Windows olması lazım (uses kısmına bak).
Kodu çalıştır bir bak sonra subitems kısmını hesaplatarak bulursun. Tıklanan koordinatı, p.x ve p.y ile alacaksın. Burada sana p.x yetecek gibi.

Aşağıdaki gibi bir çalışma yapabilirsin. Denemeden yazıyorum fikir vermesi için.

songenislik := 0;
for i := 0 to 3 do
songenislik := songenislik + listview.columns.width;

if (p.x > listview.columns[0].width) and (p.x < son_genislik) then
senin alanına tıklanmıştır.
else
hata



sanırım beni yanlış anladınız veya ben sizi anlamadım :)

ListView de 1, 2 , 3, 4. kolan dışında herhangi bir alana tıkladığında uyarı verme istiyorum bunu nasıl yapabilirim...
İşi bilen yardım eder, az bilen akıl verir, bilmeyen eleştirir, yapamayan ise çamur atar...

xxxjedixxx
Üye
Mesajlar: 216
Kayıt: 10 Ara 2013 03:50

Re: ListView kolon tıklama

Mesaj gönderen xxxjedixxx » 02 Haz 2014 07:50

Eğer bahsettiğin sütun başlıklarına tıklamak ile ilgiliyse aşağıdaki kod işini görür.

procedure TForm1.ListView1ColumnClick(Sender: TObject; Column: TListColumn);
begin
if Column.Index > 3 then
showmessage('hata');
end;

Kullanıcı avatarı
brs
Üye
Mesajlar: 626
Kayıt: 04 Eki 2012 02:52

Re: ListView kolon tıklama

Mesaj gönderen brs » 02 Haz 2014 12:34

Nerede anlaşamadık ki :) anlayamadım

Başka bir örnek vereyim listview de 3. kolonun 10. satırına tıklandığında uyarı vermek istiyorum yada 3. kolon 12. satırına tıklandığında yani 3 kolonun herhangi bir satıra tıklama yapıldığında kullanıcı uyarılacak.
İşi bilen yardım eder, az bilen akıl verir, bilmeyen eleştirir, yapamayan ise çamur atar...

xxxjedixxx
Üye
Mesajlar: 216
Kayıt: 10 Ara 2013 03:50

Re: ListView kolon tıklama

Mesaj gönderen xxxjedixxx » 02 Haz 2014 01:21

Sen yazdıklarını okuyor musun? Rica ediyorum bir oku. Son yazdığınla bir alakaları var mı bir bak. :)

Çözüme gelince ilk verdiğim örnekler yardımıyla bu istediğini rahatlıkla yapabilirsin. Biraz uğraş.

Kullanıcı avatarı
SimaWB
Üye
Mesajlar: 1311
Kayıt: 07 May 2009 09:42
Konum: İstanbul
İletişim:

Re: ListView kolon tıklama

Mesaj gönderen SimaWB » 02 Haz 2014 03:09

xxxjedixxx yazdı:Sen yazdıklarını okuyor musun? Rica ediyorum bir oku. Son yazdığınla bir alakaları var mı bir bak. :)

Çözüme gelince ilk verdiğim örnekler yardımıyla bu istediğini rahatlıkla yapabilirsin. Biraz uğraş.
ListView'da yatay scrollbar gözükürse o zaman işler karışır :wink:
There's no place like 127.0.0.1

Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4731
Kayıt: 09 Ara 2003 08:13
Konum: Ankara
İletişim:

Re: ListView kolon tıklama

Mesaj gönderen mrmarman » 02 Haz 2014 05:13

- DelphiDunyasi.NET'de de benzer bir soru sormuş ve size aşağıdaki örneği hazırlamıştım. Bu örneği buradan vererek sorman daha doğru olurdu, çünkü sorun daha anlaşılır olurdu.

- Aşağıdaki sana verdiğim kodda hatırlarsan sütunların türüne göre farklı bir nesne ( TEdit, TMaskedit veya TDateTimePicker ) bir TObject tipine bağlanıp listview içerisinde gösteriliyordu. Bunu aşağıdaki kısımdaki gibi eğer NIL ise yani herhangi bir nesneye bağlanmamış ise işlem yapmasını engellemen yeterliydi.

- yani örnekteki xSubItem 0,1,2 dışında bir sütuna ait index no barındırırsa, Nesne NIL kalacağından if Nesne <> Nil ifadesi false olacaktır. Böylece özel mesajın olan bu alana giriş yapamazsınız tarzında diayalog pencereni kullanıcıya sunabilirsin.

Kod: Tümünü seç

     Nesne := nil;
      case xSubItem of
      0: Nesne := Form1.Edit1;
      1: Nesne := Form1.MaskEdit1;
      2: Nesne := Form1.DateTimePicker1;
      end;

      if Nesne <> Nil then
      begin
        // işlemler, nesne gösterimleri vs.
      end else
      begin
        MessageDlg('Bu alanda değişiklik yapılamaz...', mtWarning, [mbOk], 0);
      end;
Resim

Kod: Tümünü seç

Uses CommCtrl;

Var
  xItem    : Integer = -1;
  xSubItem : Integer = -1;

procedure ListViewKonumlan( ListView:TListView; iItem, iSubItem:Integer );
Var
  iSayac,
  iLeft, iTop : Integer;
  strIcerik   : String;
  Nesne       : TObject;
begin
  xItem      := iItem;
  xSubItem   := iSubItem;

  iLeft      := ListView.Left + 2;
  for iSayac := xSubItem downto 0
    do iLeft := iLeft + ListView.Columns[iSayac].Width;

  iTop       := ListView.Top + 27;
  for iSayac := xItem-1 downto ListView.TopItem.Index
    do iTop  := iTop + 1 + ListView.SmallImages.Height;


  Nesne := nil;
  case xSubItem of
  0: Nesne := Form1.Edit1;
  1: Nesne := Form1.MaskEdit1;
  2: Nesne := Form1.DateTimePicker1;
  end;

  With TMaskEdit(Nesne) do
  begin
    Visible := True;
    Left    := iLeft;
    Top     := iTop;
    Width   := ListView.Columns[ xSubItem+1 ].Width;
    strIcerik := ListView.Items[ xItem ].SubItems[ xSubItem ];
    if Nesne is TMaskEdit then
    begin
      TMaskEdit(Nesne).Text       := strIcerik;
      SelectAll;
      SetFocus;
    end else
    if Nesne is TEdit     then
    begin
      TEdit(Nesne).Text           := strIcerik;
      SelectAll;
      SetFocus;
    end else
    Try
    if Nesne is TDateTimePicker then begin
      TDateTimePicker(Nesne).Date := StrToDate(strIcerik);
      // Otomatik açalım...
      TDateTimePicker(Nesne).Perform(WM_KEYDOWN, VK_F4, 0);
      TDateTimePicker(Nesne).Perform(WM_KEYUP,   VK_F4, 0);
    end;
    Except End;
    Tag     := 1;
  end;
end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
Var
  iYeniItem, iYeniSubItem : Integer;
begin
  if (Key = #13) then
  begin
    Key := #0;
    iYeniItem    := xItem;
    iYeniSubItem := xSubItem;
    if xSubItem < 2 then inc(iYeniSubItem)
    else begin
      inc(iYeniItem);
      iYeniSubItem := 0;
    end;
    ListView1.SetFocus; // Focusu Nesnemizden alalım ki içeriğini tazelesin.
    if iYeniItem <= ListView1.Items.Count-1
      then ListViewKonumlan( ListView1, iYeniItem, iYeniSubItem)
      else ShowMessage('Limite gelindi..');
  end;
end;

procedure ListViewClickEdildi( ListView:TListView );
Var
  pKoordinat  : TPoint;
  liItem      : TLIstItem;
  lvBilgi     : TLVHitTestInfo; // USES CommCtrl eklenecek..
  iSayac,
  iLeft, iTop : Integer;
  strIcerik   : String;
  Nesne       : TObject;
begin
  pKoordinat  := ListView.ScreenToClient( Mouse.CursorPos ); // Mouse Koordinatını aldık.
  liItem      := ListView.GetItemAt( pKoordinat.x, pKoordinat.y ); // Koordinata göre hangi item olduğunu öğrendik.
  // Gerisi Hikaye... :)
  If Assigned( liItem ) then
  begin // Item'in kendisi tıklanmış, olsa olsa Caption kısmıdır.
    ShowMessageFmt( '(%d) nolu item tıklandı, içinde "%s" yazıyor...', [liItem.Index, liItem.Caption] )
  end else
  begin // SubItem üzerinde tıklanmış demektir.
    FillChar( lvBilgi, sizeof( lvBilgi ), 0 ); // içeriği boşalttık...
    lvBilgi.pt   := pKoordinat;

    if  ListView.Perform( LVM_SUBITEMHITTEST, 0, lparam(@lvBilgi)) <> -1 then
    begin // Artık elimizde listview'den detay bilgiyi edindik.
      // Edit'i Visible edip ListView üzerinde hangi hücreye (subitem)
      // adapte edeceğimizi biliyoruz.
      // Onun için ilgili Edit'i o hücreye konumlandırıp
      // ona göre daraltıp, içine hücredeki bilgiyi yazıyoruz
      // ve edit'i focus edip içindeki yazılanların tümünü seçtiricez...

      iLeft      := ListView.Left + 2;
      for iSayac := lvBilgi.iSubItem-1 downto 0
        do iLeft := iLeft + ListView.Columns[iSayac].Width;

      iTop       := ListView.Top + 27;
      for iSayac := lvBilgi.iItem-1 downto ListView.TopItem.Index
        do iTop  := iTop + 1 + ListView.SmallImages.Height;

      xItem      := lvBilgi.iItem;
      xSubItem   := lvBilgi.iSubItem-1;

      Nesne := nil;
      case xSubItem of
      0: Nesne := Form1.Edit1;
      1: Nesne := Form1.MaskEdit1;
      2: Nesne := Form1.DateTimePicker1;
      end;

      if Nesne <> Nil then
      begin
        With TMaskEdit(Nesne) do
        begin
          Visible := True;
          Left    := iLeft;
          Top     := iTop;
          Width   := ListView.Columns[ lvBilgi.iSubItem ].Width;
          strIcerik := ListView.Items[ lvBilgi.iItem ].SubItems[ lvBilgi.iSubItem-1 ];
          Try
          if Nesne is TDateTimePicker then begin
            TDateTimePicker(Nesne).Date := StrToDate(strIcerik);
            // Otomatik açalım...
            TDateTimePicker(Nesne).Perform(WM_KEYDOWN, VK_F4, 0);
            TDateTimePicker(Nesne).Perform(WM_KEYUP, VK_F4, 0);
          end;
          Except End;
          if Nesne is TMaskEdit       then TMaskEdit(Nesne).Text       := strIcerik;
          if Nesne is TEdit           then TEdit(Nesne).Text           := strIcerik;
          Tag     := 1;
          SelectAll;
          SetFocus;
        end;
      end else
      begin
        MessageDlg('Bu alanda değişiklik yapılamaz...', mtWarning, [mbOk], 0);
      end;
    end;
  end;
end;

procedure TForm1.ListView1Click(Sender: TObject);
begin
  ListViewClickEdildi( TListView(Sender) );
end;

procedure TForm1.Edit1Exit(Sender: TObject);
begin
  if TEdit(Sender).Tag > 0 then
  begin
    ListView1.Items[xItem].SubItems[xSubItem] := TEdit(Sender).Text;
    TEdit(Sender).Tag     := -1;
    TEdit(Sender).Visible := False;
  end;
end;

procedure TForm1.MaskEdit1Exit(Sender: TObject);
begin
  if TMaskEdit(Sender).Tag > 0 then
  begin
    ListView1.Items[xItem].SubItems[xSubItem] := TMaskEdit(Sender).Text;
    TMaskEdit(Sender).Tag     := -1;
    TMaskEdit(Sender).Visible := False;
  end;
end;

procedure TForm1.DateTimePicker1Exit(Sender: TObject);
begin
  if TDateTimePicker(Sender).Tag > 0 then
  begin
    ListView1.Items[xItem].SubItems[xSubItem] := DateToStr( TDateTimePicker(Sender).Date );
    TDateTimePicker(Sender).Tag     := -1;
    TDateTimePicker(Sender).Visible := False;
  end;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  ImageList1.Width  := 22;   // içinde resim olması şart değil. ListView'in
  ImageList1.Height := 22;   // Item'inin yüksekliğini biz belirlemek için kullanıyoruz.
  With ListView1 do
  begin
    ViewStyle   := vsReport;
    GridLines    := True;
    RowSelect   := False;
    SmallImages := ImageList1;
    With Columns.Add do Caption := 'Başlık';
    With Columns.Add do Caption := 'Bilgi_01';
    With Columns.Add do Caption := 'Bilgi_02';
    With Columns.Add do Caption := 'Bilgi_03';
    With Columns.Add do Caption := 'Bilgi_04';

    ListView1.Columns[0].Width := 50;
    ListView1.Columns[1].Width := 100;
    ListView1.Columns[2].Width := 100;
    ListView1.Columns[3].Width := 200;
    ListView1.Columns[4].Width := 100;
  end;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  With ListView1.Items.Add do
  begin
    Caption := IntToStr( ListView1.Items.Count) ;
    SubItems.Add( 'A' );
    SubItems.Add( '  .  .    ' );
    SubItems.Add( DateToStr(now) );
    SubItems.Add( 'Burada işlem yapmasın' );
  end;
end;
Dosya ekleri
ListView_Edit_Ornegi.rar
ListView - EDIT, MASKEDIT ve DATETIMEPICKER örneği
(250.19 KiB) 90 kere indirildi
Resim Resim

Kullanıcı avatarı
brs
Üye
Mesajlar: 626
Kayıt: 04 Eki 2012 02:52

Re: ListView kolon tıklama

Mesaj gönderen brs » 03 Tem 2014 10:18

Hocam listview de scroll sağa veya sola çektiğimde edit sağa veya sola nasıl taşıya bilirim listview scroll pozition çok araştırdım fakat bir şey bulamadım...
İşi bilen yardım eder, az bilen akıl verir, bilmeyen eleştirir, yapamayan ise çamur atar...

Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4731
Kayıt: 09 Ara 2003 08:13
Konum: Ankara
İletişim:

Re: ListView kolon tıklama

Mesaj gönderen mrmarman » 04 Tem 2014 10:07

Bunun sana verdiğim kod örneği kadar işçiliği var. ListView'in scroll özelliğini algılamak için
(1) TListView sınıfını özelleştirmek,
(2) ardından da scroll edildiğini algıladığında onclick eventini tetiklemek.
(3) onclick eventinde yapılanlara, ListView'in ne kadar scroll yaptığını okumak
(4) Edit açık olan subitem halen görünür halde mi sormak
(5) Görünür haldeyse, scrollbar aktif olduğuna göre ne kadarlık bir bütününün göründüğünü ölçmek.
(6) Soldan görünür olan ilk subitem'e ait indexi bulup, 0'dan değil o indexten itibaren genişlik saydırıp left değerini bulmak
(7) Bu bilgiler ışığında edit control'ü modifiye etmek veya yok etmek işlerini yapmak gerekiyor.


Bunu, bize sorduğun sorulardan incelediklerim çerçevesinde kendi başına yapman zaman alacaktır.

Önerim listview'in görünen sütunlarını daraltarak bütününü koruman veyahut girişleri inputbox formuna dönüştürmen şeklindedir.
Resim Resim

Cevapla