Как сделать активными только определенные дни недели в DatePicker

240
17 апреля 2022, 18:20

Я получаю порядковые номера определенных дней недели из базы данных и эти дни должны оставаться активными в DatePicker, а все остальные - нет. Но в итоге получается так, что все дни в календаре неактивны, кроме последнего (у меня это последний день года). Что я делаю не так? За основу брала код по ссылке: https://stackoverflow.com/questions/24213801/how-to-black-out-specific-days-of-the-week-datepicker-vb (он работает).

using (OracleConnection conn = new OracleConnection(connectionString))
{
    int year = DateTime.Now.Year;
    var minDate = DateTime.Now;
    var maxDate =new DateTime(year, 12, 31);
    string r;
    string st = comboBox2.SelectedItem.ToString();
    string sql3 = "select distinct id_week from timetable,masters where 
    timetable.id_mas=masters.cod and masters.fio = '" + st + "'";
    using (OracleCommand command = new OracleCommand(sql3, conn))
    {
        OracleDataReader reader3 = command.ExecuteReader();
        while (reader3.Read())
        {
            r = reader3[0].ToString();
            for (var d = minDate; d <= maxDate> d; d = d.AddDays(1))
            {
                if ((int)d.DayOfWeek != Convert.ToInt32(r))
                {
                    dateTimePicker1.BlackoutDates.Add(new CalendarDateRange(d));
                }
            }
        }
        reader3.Close();
    }
}
Answer 1

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

Соответственно, у вас при проходе в while в первый раз находится понедельник.

Внутри while в цикле for вы удаляете все дни, кроме понедельника. Окей, пусть так.

Второй проход while идёт по вторнику. Внутри while вы снова входите в for, в котором удаляете все дни, кроме вторника. Но ведь там оставались только понедельники, верно? Значит, вы просто удаляете все оставшиеся дни.

Такой алгоритм будет выглядеть рабочим только если в базе у вас зашит один день недели.

Как сделать алгоритм рабочим? Ну, как вариант - я бы сначала прочитал все дни недели из базы в массив дней недели - а потом проверял бы, что текущий день из цикла for находится в этом массиве.

Ну вот как-то вот так:

var days = new[] {1, 2};
var minDate = DateTime.Now;
var maxDate = new DateTime(2020, 12, 31);
for (var d = minDate; d <= maxDate; d = d.AddDays(1))
{
    if (days.Any(x => x == (int)d.DayOfWeek))
    {
        d.Dump();
    }
}

Вывод для оставшихся дней в 2020 году:

(инвертируйте условие в if для получения дней которые нужно убрать из календаря)

А вот так могла выглядеть чисто linq-версия этого же кода:

var startDate = DateTime.Today;
var finishDate = new DateTime(2020, 12, 31);
var dateDiff = finishDate - startDate;
var daysOfWeek = new[] { 1, 2 };
var result = Enumerable.Range(1, dateDiff.Days)
                       .Select(x => startDate.AddDays(x))
                       .Where(x => daysOfWeek.Any(y => y == (int)x.DayOfWeek))
                       .ToList();
READ ALSO
Как увеличить offset для elasticsearch?

Как увеличить offset для elasticsearch?

Эластик имеет настройку indexmax-result-window по дефолту равную 10000, поэтому при запросе с offset > 10000, я получаю ошибку

162
Возможно ли отправить в БД тип данных object?

Возможно ли отправить в БД тип данных object?

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

138