Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Edit Kontrol DatePicker gibi Kullanma
#1
Merhaba,

TEdit sınıfında türetilmiş kendimce özelleştirdim çok fonksiyonlu bir edit kontrolüm var.
Ben bu Editi isterse string giriş ister para girişi ister tarih istersem numeric giriş olarak kullanabiliyorum.

Yapmak istediğim Editin modunu Tarih seçtiğimde (tarih girişini alacak formatlayacak) kendisi otomatik olarak tarih olarak formatlıyor. Kullanımı oldukça hızlı ve pratik oluyor. 

Buraya kadar sorun yok. Fakat bazı durumlarda kullanıcı takvim üzerinden tarih seçimini yapmak istiyor. İleriye dönük günleri görerek mantıklı bir tarih vermek için böyle bir isteği var.

Bu durumda nasıl bir öneriniz olur. DateTimePicker gibi Tarih ikon/bitbutton u(bu draw işini design ve run time ikisinde de çalışmalı) ve üzerine tıklanınca açılan bir Takvim ile mi?
Yoksa Edit üzerine çift tıklayarak açılan bir takvim üzerinden mi seçtirmeliyim.

Data önce edit içine birşeyler çizmek istediğimde bayağı sorun olmuştu. Nihayetinde WndProc ve Repaint event leri içinde Canvas ile ufak bir kare çizmiştim.

Hazır componentler var. Fakat ben bunları kullanmak istemiyorum. Projeye dahil edilen her component ya lisans yada tekrardan kurulum ihtiyacı doğuruyor. Mümkün olduğunca Base kontroller üzerinde değişiklik yaparak kullanmak projeyi direkt derlemeye yardımcı oluyor. cxDateEdit tam olarak istediğim gibi diyebilirim veya jvDateEdit
PostgreSQL - Linux - Delphi, Poliüretan
WWW
Cevapla
#2
Merhaba.

Ben olsaydım şöyle yapardım.
  • Visible false olan bir TDateTimePicker'i Edit'e Focus olunduğunda Visible True yapar, 
  • TDateTimePicker'in Left, Top değerlerini de TEdit'in hemen altına konumlandır,
  • Seçime hazır olsun diye Edit'in içinde tarih varsa onu, yoksa bugünün tarihi seçili halde PopUp ettirir,
  • Seçim yapmak isteyen DateTimePicker'den seçer, istemeyen direk Edit'e elle girmesini bekler, 
  • Seçim TDateTimePicker üzerinden yapılırsa hedef TEdit içeriğini seçil olan ile değiştirilip DateTimePicker'in Visible False eder,
  • Focus Form'a çekerdim....
Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif
Cevapla
#3
Bilgisayar başında bir kurgu hazırladım.


Const
  FEditMask  = '!99/99/9999;1;_';
  FEmpty     = '  .  .    ';
var
  FPickerReturn : Boolean = false;

procedure TForm1.FormCreate(Sender: TObject);
begin
  With MaskEdit1 do begin
    EditMask        := FEditMask;
    OnEnter         := MaskEdit1Enter;
    Text            := '';
    Tag             := 2;
  end; // with
  DateTimePicker1.Visible   := False;
  DateTimePicker1.OnCloseUp := DateTimePicker1CloseUp;
end;

procedure TForm1.MaskEdit1Enter(Sender: TObject);
begin
  if FPickerReturn then begin
    FPickerReturn := False;
    Exit;
  end;

  DateTimePicker1.Tag := TMaskEdit(Sender).Tag;

  if TMaskEdit(Sender).Text <> FEmpty
  then
    DateTimePicker1.DateTime := StrTodateTime( TMaskEdit(Sender).Text )
  else
    DateTimePicker1.DateTime := Int(Now);

  With DateTimePicker1 do begin
    Left  := TMaskEdit(Sender).Left;
    Top   := TMaskEdit(Sender).Top;
    Width := TMaskEdit(Sender).Width;

    Visible := True;
    Perform( wm_keydown,  vk_f4, 0 );
    Perform( wm_keyup,    vk_f4, 0 );
    SetFocus;
  end; // with
end;

procedure TForm1.DateTimePicker1CloseUp(Sender: TObject);
begin
  case TDateTimePicker(Sender).Tag of
  2: MaskEdit1.Text := FormatDateTime('dd/mm/yyyy',  DateTimePicker1.DateTime );
  end;
  TDateTimePicker(Sender).Visible := False;
  FPickerReturn := True;
  MaskEdit1.SetFocus;
end;



xwmdlun9mik223r1jbu3.gif
Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif
Cevapla
#4
@mrmarman senin gösterdiğin mantıkla yaptım gayet başarılı mantıklı oldu.

Teşekkürler gayet kullanışlı oldu. Daha sonra tarih formatını yerel bilgisayar ayarlarındaki shortdate formatında alarak güncelleme yapacağım. Şu anda buda benim işimi görüyor.

constructor TEdit.Create(AOwner: TComponent);
  if DatePicker = nil then
  DatePicker := TDateTimePicker.Create(Self);
  DatePicker.Visible := False;
  DatePicker.OnCloseUp := DatePickerCloseUp;
end;

procedure TEdit.DatePickerCloseUp(Sender: TObject);
begin
  Self.Text := FormatDateTime('dd/mm/yyyy', DatePicker.DateTime);
  TDateTimePicker(Sender).Visible := False;
  FPickerReturn := False;
  Self.SetFocus;
end;

procedure TEdit.MyOnKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if (Key = VK_F1) then
  begin
    if thsInputDataType = itDate then
    begin
      if Self.Enabled and not Self.ReadOnly then
      begin
        if FPickerReturn then begin
          FPickerReturn := False;
          Exit;
        end;

        DatePicker.Parent := Self.Parent;
        DatePicker.SendToBack;

        if (Self.Text <> '') then
          DatePicker.DateTime := StrTodateTime( Self.Text )
        else
          DatePicker.DateTime := Int(Now);

        DatePicker.Left  := Self.Left;
        DatePicker.Top   := Self.Top;
        DatePicker.Width := Self.Width;

        DatePicker.Visible := True;
        DatePicker.Perform( WM_KEYDOWN,  VK_F4, 0);
        DatePicker.Perform( WM_KEYUP,    VK_F4, 0);

        DatePicker.Visible := True;
      end;
    end
    else
    begin
      if Assigned(FOnHelperProcess) then
        FOnHelperProcess(Self);
    end;
  end;
end;



PostgreSQL - Linux - Delphi, Poliüretan
WWW
Cevapla
#5
Bir önerim olabilir mi? Bunu bir bileşen olarak tasarladığınızı bildirmiştiniz.

Constructor/create anında her Edit için bir TDateTimePicker create üreterek çift oluşturduğunuzu görüyorum.

Bu edit ekranda görünen onlarca veya create edilmiş ama show edilmemiş formlarda da create edilmiş olduğu ihtimali akla gelince yüzlerce adet olabilir.

Bu durumda henüz onEnter olmamış her sizin edit bileleni için kullanım dışı boşta duran TDateTimePicker bulunması hafıza yönetimi için pek ekonomik görünmedi.

Şöyle bir çözüm önerim var, onEnter olunca dinamik olarak create edip, create edilen TDateTimePicker'in kapatılıp focus değişim anında da freeandnil edilmesi verimi arttıracağı kanaatindeyim.

Başarılar.


EKLEME :

Anlatmak istediğim kabaca şu şekilde bir yapı. ( datetime hata kontrolleri yapılmamıştır )


unit DateTimeMaskU;

interface

Uses WinApi.Windows, WinApi.Messages, System.Classes, System.SysUtils, Vcl.Mask, Vcl.ComCtrls, Vcl.Controls;

type
  TDateTimeMask = Class(Vcl.Mask.TMaskEdit)
  private
    { Private declarations }
  Const
    FEditMask  = '!99/99/9999;1;_';
    FEmpty     = '  .  .    ';
    procedure   DateTimePickerCloseUp(Sender: TObject);
    procedure   MaskEditOnEnter(Sender: TObject);
  var
    FDateTimePicker : Vcl.ComCtrls.TDateTimePicker;
    FPickerReturn   : Boolean;
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor  Destroy; override;
  end;

  procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Sample Comp Set', [TDateTimeMask]);
end;

{ TDateTimeMask }

constructor TDateTimeMask.Create(AOwner: System.Classes.TComponent);
begin
inherited Create(AOwner);

  Height  := 24;
  Width   := 120;

  FPickerReturn   := False;
  EditMask        := FEditMask;
  OnEnter         := MaskEditOnEnter;
  Text            := '';
end;

destructor TDateTimeMask.Destroy;
begin
  if Assigned( FDateTimePicker ) then begin
    FDateTimePicker.OnCloseUp := nil;
    FreeAndNil( FDateTimePicker );
  end;

  inherited;
end;

procedure TDateTimeMask.DateTimePickerCloseUp(Sender: TObject);
begin
  Text := FormatDateTime('dd/mm/yyyy',  TDateTimePicker(Sender).DateTime );
  TDateTimePicker(Sender).Visible := False;
  FPickerReturn := True;
  SetFocus;
  FreeAndNil( FDateTimePicker );
end;

procedure TDateTimeMask.MaskEditOnEnter(Sender: TObject);
begin
  if FPickerReturn then begin
    FPickerReturn := False;
    Exit;
  end;

  FDateTimePicker := TDateTimePicker.Create(nil);
  With FDateTimePicker do begin
    Parent    := TDateTimeMask(Sender).Parent;
    Left      := TDateTimeMask(Sender).Left;
    Top       := TDateTimeMask(Sender).Top;
    Width     := TDateTimeMask(Sender).Width;
    OnCloseUp := DateTimePickerCloseUp;

    if TDateTimeMask(Sender).Text <> FEmpty
    then
      DateTime := StrTodateTime( TDateTimeMask(Sender).Text )
    else
      DateTime := Int(Now);

    Visible   := True;
    Perform( WinApi.Messages.WM_KEYDOWN,  WinApi.Windows.VK_F4, 0 );
    Perform( WinApi.Messages.WM_KEYUP,    WinApi.Windows.VK_F4, 0 );
    SetFocus;
  end; // with
end;

end.

a3qhkhpvzbyfejclarb0.gif
Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif
Cevapla
#6
@mrmarman hocam haklısınız. Sonuçta form üzerinde bulunan edit (modu date ise) tarih girişi için kullanılacaksa datetimepicker ihtiyacı var ve sadece F1 tuşu ile açıyorum. İhtiyaç anında oluşturup akabinde free yapmak daha doğru. Diğer durumlarda gereksiz hafıza kullanımı olacak.
PostgreSQL - Linux - Delphi, Poliüretan
WWW
Cevapla
#7
@3ddark  o kısımları düşünmemiştim bile, yani hiç TDateTimePicker ihtiyacı olmayan mode kullanım opsiyonunu.. Büyüksün Smile
Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Delphi virus gibi deutsch1988 14 768 Dün, Saat: 10:21
Son Yorum: engerex
  Edit içindeki tarihin doğru olup olmadığını kontrol etmek? hasansavci 2 412 17-10-2023, Saat: 03:35
Son Yorum: mcuyan
  DBGrid'i Çok Fonksiyonlu Kullanma bünyamin68 10 2.845 17-12-2022, Saat: 22:37
Son Yorum: zuluman
  delphi combobox edit yunusemre 6 1.679 19-05-2022, Saat: 22:50
Son Yorum: mcuyan
  Class Tanımlama ve Kullanma-Not Found Hatası nehirnnn 2 787 08-12-2021, Saat: 12:31
Son Yorum: mrmarman



Konuyu Okuyanlar: 1 Ziyaretçi