Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > TMonthCalendar


Автор: Akella 31.1.2005, 15:03
 Как определить "по-уму", так сказать, что пользователь ткнул мышкой именно по дате, а то при переключении месяца, тоже выбирается дата.

Код

procedure TfmDate.MonthCalendar1Click(Sender: TObject);
begin
  Edit1.Text:=Edit1.Text + IntToStr(DateUtils.DayOf(MonthCalendar1.Date)) +';';
end;

Автор: Druidik25 31.1.2005, 16:28
Меняется дата, но не меняется месяц. Сохрани в глобальной переменной дату, и если она изменилась - держи результат. Осталось проверять при изменении даты - поменялось число или месяц.
Можно дату разделить на месяц год и число и таким же "методом".

Автор: Akella 31.1.2005, 16:30
Мне кажется, что это не выход.
Попробуем smile
Добавлено @ 16:36
Смотрим, что получается на рисуночке smile
1. Щелкаем по дате 31 янв.
2. Ниже в TEdit попадает значание 31;
3. Щелкаем по кнопке переключения месяца.
4. Ниже в TEdit попадает значание 31;28;
Такого быть не должно, нужно просто переключить месяц.

Код

dDate - глобальная переменная
procedure TfmDate.MonthCalendar1Click(Sender: TObject);
begin
 if MonthCalendar1.Date = dDate then Exit;
 Edit1.Text:=Edit1.Text + IntToStr(DateUtils.DayOf(MonthCalendar1.Date)) +';';
end;


Автор: Akella 31.1.2005, 16:37
А если переключать месцы туда-обратно, то все время будет 28


Автор: z-END 31.1.2005, 16:46
может немного усложнить и сделать по нормальному?:
создать массив дат, (отображать его в TListBox подобном слева(справа) от твоего календаря).
при добавлении новой даты добавлять его в массив и в список, при отмене - удалять..
усложнится все не намного зато удобства будутsmile

Автор: NiJazz 31.1.2005, 16:53
dsergey
А что хотелось бы при переключении месяца?

Автор: Druidik25 31.1.2005, 16:54
Можно сохранить таблицу максимальных дат месяцев и если дата стала максимальной, а была большей чем эта но в другом месяце, то её не ставить. Это как вариант, хотя могут терятся числа. Хотя если они должны выбираться из одного месяца - это должно помочь. Но если выбирать все наибольшие подряд - то не сработает.
Если из меесяца берется число хотя бы одно из меньших - то всё супер.

Автор: <Spawn> 31.1.2005, 16:57
Цитата
добавлять его в массив и в список


Зачем добавлять в массив и в список, если достаточно одного списка? Метод IndexOf поможет найти существующие элементы.

Автор: Akella 31.1.2005, 16:59
Цитата(NiJazz @ 31.1.2005, 16:53)
dsergey
А что хотелось бы при переключении месяца?

Только "смена картинки", в TEdit ничего попадать не должно

т.е. пользователь выбирает пару дней, переключает ся на другой месяц и продолжает выбирать дни, неужели так сложно.

Автор: Druidik25 31.1.2005, 17:01
Если он выбирает с интервалом до полмесяца - тогда мой вариант - работает...
Запоминать надо день и месяц.

На крайний случай нарисовать свой календарь, но гемора много. А перехватывать нажатие кнопки в компоненте не умею.

Автор: <Spawn> 31.1.2005, 17:05
Код

procedure TForm1.MonthCalendar1Click(Sender: TObject);
var
 Day: Integer;
begin
 Day := DayOf(MonthCalendar1.Date);
 if Day <> DayOf(dDate) then
 begin
   Edit1.Text:=Edit1.Text + IntToStr(Day)+';';
   dDate := MonthCalendar1.Date; //Это я для проверки поставил сюда:)
 end;
end;

Автор: Akella 31.1.2005, 17:10
<Spawn>, криво работает.
нормально работает, если переключаться второй раз и более.

Автор: z-END 31.1.2005, 17:16
Вот код: при двойномкличе на дате, она выделяется и заносится в список дат, при повторном клике она удаляется оттуда...
Код

procedure TForm1.MonthCalendar1DblClick(Sender: TObject);
Var
Idx:Integer;
begin
Idx := Dates.IndexOf (DateToStr (MonthCalendar1.Date));
if Idx>-1
then Dates.Delete (IDx)
else Dates.Add (DateToStr (MonthCalendar1.Date));
MonthCalendar1.Date := IncMonth (MonthCalendar1.Date);
MonthCalendar1.Date := IncMonth (MonthCalendar1.Date,-1);
end;

procedure TForm1.MonthCalendar1GetMonthInfo(Sender: TObject;
 Month: Cardinal; var MonthBoldInfo: Cardinal);
var
x: Integer;
Cdate: TDate;
BDates: array of Cardinal;
begin
if Dates = nil then
begin
 Dates := TStringList.Create;
 Dates.Sorted := True;
 Dates.Duplicates := dupIgnore;
end;
for x := 0 to Dates.Count - 1 do
begin
CDate := StrToDate( Dates [x]);
if MonthOf(CDate)=Month then
begin
 SetLength (BDates, Length(BDates) + 1);
 BDates[ length(BDates)-1] := DayOf(CDate);
end;
end;
if Length (BDates) > 0 then MonthCalendar1.BoldDays (BDates, MonthBoldInfo);
Setlength(BDates,0);
end;

По-моему решение для твоих нескольких тем сразу=)

Автор: <Spawn> 31.1.2005, 17:16
Тогда вот так:

Код

var
 Form1: TForm1;
 LastMonth: integer;

implementation

{$R *.dfm}

procedure TForm1.MonthCalendar1Click(Sender: TObject);
var
 Month: Integer;
begin
 Month := MonthOf(MonthCalendar1.Date);
 if Month = LastMonth then
   Edit1.Text:=Edit1.Text + IntToStr(DayOf(MonthCalendar1.Date)) + ';'
 else
   LastMonth := Month;
end;

Автор: Akella 31.1.2005, 17:19
Общим решением собрания принят код, любезно предоставленный <Spawn`ом>, т.к. компактный и понятный. Всем спасибо. Тебе плюсик, <Spawn>

Автор: Druidik25 31.1.2005, 17:22
Код

var dday,dmonth:byte;
     mon[1..12] of byte;
...
procedure TForm1.MonthCalendar1Click(Sender: TObject);
var
Day: Integer;
begin
Day := DayOf(MonthCalendar1.Date);
if Day <> (dday)and(mon[MonthOf(MonthCalendar1.Date)]<>dday)and(dmonth<>MonthOf(MonthCalendar1.Date)) then
begin
  Edit1.Text:=Edit1.Text + IntToStr(Day)+';';
  dday := DayOf(MonthCalendar1.Date);
  dmonth:=MonthOf(MonthCalendar1.Date);
end;
end;


Сори не на чем проверить, Делфи под рукой нет.

Автор: <Spawn> 31.1.2005, 17:27
//Только для полной верности при создании формы инициализируй значение LastMonth

Код

procedure TForm1.FormCreate(Sender: TObject);
begin
 LastMonth := MonthOf(MonthCalendar1.Date)
end;

Автор: Akella 31.1.2005, 17:29
вообще-то нормально работало из без этого

Автор: Akella 2.2.2005, 16:48
z-END, смотри рисунок (справа)
такая строчка нужна
Edit1.Text:=Edit1.Text + IntToStr(DateUtils.DayOf(MonthCalendar1.Date)) +';';
а именно
Вот, что нужно в конечном итоге
Edit1.Text:= '1;2;3;5;6;8;';
Добавлено @ 16:49
в OnClick, после
MonthCalendar1.Date := IncMonth (MonthCalendar1.Date);
MonthCalendar1.Date := IncMonth (MonthCalendar1.Date,-1);

ставлю
For r:=0 to Dates.Count-1 do
Edit1.Text := Edit1.Text + ';' + Copy(Dates.ValueFromIndex[r],1,POS(DateSeparator,Dates.ValueFromIndex[r])-1);
пока нифига не получается
Добавлено @ 16:55
Пришлось пока отрубить твою процедуру

Автор: Druidik25 2.2.2005, 17:10
А мой код не проверял??? Ведь он не будет работать только в случае, если человек выбирает максимальный день месяца, отличного от текущего, при условии что выбранный месяц в количестве дней меньше предыдущевыбранного числа. Или я слишком замутил????

Автор: Akella 2.2.2005, 17:26
ну и где же твой код?

Итак, что нужно? Нужно чтобы пользователь открыл окно с календарем, выбирая даты видел бы их в TEdit`е (с этом проблем нет), хотелочсь бы подсвечивать даты жирным.

Автор: Druidik25 2.2.2005, 19:07
Цитата(Druidik25 @ 31.1.2005, 17:22)
Код

var dday,dmonth:byte;
     mon[1..12] of byte;
...
procedure TForm1.MonthCalendar1Click(Sender: TObject);
var
Day: Integer;
begin
Day := DayOf(MonthCalendar1.Date);
if Day <> (dday)and(mon[MonthOf(MonthCalendar1.Date)]<>dday)and(dmonth<>MonthOf(MonthCalendar1.Date)) then
begin
  Edit1.Text:=Edit1.Text + IntToStr(Day)+';';
  dday := DayOf(MonthCalendar1.Date);
  dmonth:=MonthOf(MonthCalendar1.Date);
end;
end;


Сори не на чем проверить, Делфи под рукой нет.

Вот.

А на счёт жирности, то пока не знаю как.
Добавлено @ 19:09
Но придумать вполне возможно.

Автор: Akella 3.2.2005, 10:12
Druidik25, твой код слишком сложен, смотри первый топик (всего одна строчка и без заморочки) - все гениальное - просто

Код

procedure TfmDate.MonthCalendar1Click(Sender: TObject);
begin
Edit1.Text:=Edit1.Text + IntToStr(DateUtils.DayOf(MonthCalendar1.Date)) +';';
end;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)