Я сейчас использую .Net 3.5.
Прямо сейчас я использую трюк using
для отключения и включения событий вокруг определенных разделов кода. Пользователь может изменить либо дни, часы, минуты или общее количество минут, и это не должно вызывать бесконечный каскад событий (например, общее изменение минут, общее изменение минут и т. Д.). В то время как код выполняет то, что я хочу, может быть лучше / более прямой путь. Вы знаете кого-нибудь?
Для мускулистых очков:
Этот элемент управления будет использоваться несколькими командами - я не хочу смущать его. Я подозреваю, что мне не нужно заново изобретать колесо при определении часов в дне, дней в неделе и т. Д. Некоторые другие стандартные библиотеки .Net там должны иметь его. Любые другие замечания относительно кода? Это using (EventHacker.DisableEvents(this))
бизнес - это должно быть обычным делом в .Net ... временное изменение настроек. Как это называется? Я хотел бы иметь возможность ссылаться на него в комментарии, а также читать больше о текущих реализациях. В общем случае необходимо запомнить не только дескриптор изменяемой вещи, но и предыдущее состояние (в этом случае предыдущее состояние не имеет значения - события включаются и выключаются безоговорочно). Тогда есть также возможность multi-threaded hacking
. Можно также использовать дженерики, чтобы сделать код, возможно, чище. Выяснение всего этого может привести к многостраничному сообщению в блоге. Я был бы рад услышать некоторые ответы.
P.S. Кажется ли, что я страдаю от обсессивно-компульсивного расстройства? Некоторые люди любят закончить дела и двигаться дальше; Мне нравится держать их открытыми ... всегда есть лучший способ.
// Corresponding Designer class is omitted.
using System;
using System.Windows.Forms;
namespace XYZ // Real name masked
{
interface IEventHackable
{
void EnableEvents();
void DisableEvents();
}
public partial class PollingIntervalGroupBox : GroupBox, IEventHackable
{
private const int DAYS_IN_WEEK = 7;
private const int MINUTES_IN_HOUR = 60;
private const int HOURS_IN_DAY = 24;
private const int MINUTES_IN_DAY = MINUTES_IN_HOUR * HOURS_IN_DAY;
private const int MAX_TOTAL_DAYS = 100;
private static readonly decimal MIN_TOTAL_NUM_MINUTES = 1; // Anything faster than once per minute can bog down our servers.
private static readonly decimal MAX_TOTAL_NUM_MINUTES = (MAX_TOTAL_DAYS * MINUTES_IN_DAY) - 1; // 99 days should be plenty.
// The value above was chosen so to not cause an overflow exception.
// Watch out for it - numericUpDownControls each have a MaximumValue setting.
public PollingIntervalGroupBox()
{
InitializeComponent();
InitializeComponentCustom();
}
private void InitializeComponentCustom()
{
this.m_upDownDays.Maximum = MAX_TOTAL_DAYS - 1;
this.m_upDownHours.Maximum = HOURS_IN_DAY - 1;
this.m_upDownMinutes.Maximum = MINUTES_IN_HOUR - 1;
this.m_upDownTotalMinutes.Maximum = MAX_TOTAL_NUM_MINUTES;
this.m_upDownTotalMinutes.Minimum = MIN_TOTAL_NUM_MINUTES;
}
private void m_upDownTotalMinutes_ValueChanged(object sender, EventArgs e)
{
setTotalMinutes(this.m_upDownTotalMinutes.Value);
}
private void m_upDownDays_ValueChanged(object sender, EventArgs e)
{
updateTotalMinutes();
}
private void m_upDownHours_ValueChanged(object sender, EventArgs e)
{
updateTotalMinutes();
}
private void m_upDownMinutes_ValueChanged(object sender, EventArgs e)
{
updateTotalMinutes();
}
private void updateTotalMinutes()
{
this.setTotalMinutes(
MINUTES_IN_DAY * m_upDownDays.Value +
MINUTES_IN_HOUR * m_upDownHours.Value +
m_upDownMinutes.Value);
}
public decimal TotalMinutes
{
get
{
return m_upDownTotalMinutes.Value;
}
set
{
m_upDownTotalMinutes.Value = value;
}
}
public decimal TotalHours
{
set
{
setTotalMinutes(value * MINUTES_IN_HOUR);
}
}
public decimal TotalDays
{
set
{
setTotalMinutes(value * MINUTES_IN_DAY);
}
}
public decimal TotalWeeks
{
set
{
setTotalMinutes(value * DAYS_IN_WEEK * MINUTES_IN_DAY);
}
}
private void setTotalMinutes(decimal nTotalMinutes)
{
if (nTotalMinutes < MIN_TOTAL_NUM_MINUTES)
{
setTotalMinutes(MIN_TOTAL_NUM_MINUTES);
return; // Must be carefull with recursion.
}
if (nTotalMinutes > MAX_TOTAL_NUM_MINUTES)
{
setTotalMinutes(MAX_TOTAL_NUM_MINUTES);
return; // Must be carefull with recursion.
}
using (EventHacker.DisableEvents(this))
{
// First set the total minutes
this.m_upDownTotalMinutes.Value = nTotalMinutes;
// Then set the rest
this.m_upDownDays.Value = (int)(nTotalMinutes / MINUTES_IN_DAY);
nTotalMinutes = nTotalMinutes % MINUTES_IN_DAY; // variable reuse.
this.m_upDownHours.Value = (int)(nTotalMinutes / MINUTES_IN_HOUR);
nTotalMinutes = nTotalMinutes % MINUTES_IN_HOUR;
this.m_upDownMinutes.Value = nTotalMinutes;
}
}
// Event magic
public void EnableEvents()
{
this.m_upDownTotalMinutes.ValueChanged += this.m_upDownTotalMinutes_ValueChanged;
this.m_upDownDays.ValueChanged += this.m_upDownDays_ValueChanged;
this.m_upDownHours.ValueChanged += this.m_upDownHours_ValueChanged;
this.m_upDownMinutes.ValueChanged += this.m_upDownMinutes_ValueChanged;
}
public void DisableEvents()
{
this.m_upDownTotalMinutes.ValueChanged -= this.m_upDownTotalMinutes_ValueChanged;
this.m_upDownDays.ValueChanged -= this.m_upDownDays_ValueChanged;
this.m_upDownHours.ValueChanged -= this.m_upDownHours_ValueChanged;
this.m_upDownMinutes.ValueChanged -= this.m_upDownMinutes_ValueChanged;
}
// We give as little info as possible to the 'hacker'.
private sealed class EventHacker : IDisposable
{
IEventHackable _hackableHandle;
public static IDisposable DisableEvents(IEventHackable hackableHandle)
{
return new EventHacker(hackableHandle);
}
public EventHacker(IEventHackable hackableHandle)
{
this._hackableHandle = hackableHandle;
this._hackableHandle.DisableEvents();
}
public void Dispose()
{
this._hackableHandle.EnableEvents();
}
}
}
}