Я нашел вопрос, который, как я полагаю, это то, что я искал, но были некоторые вещи, которые я не следовал в ответах. Поэтому я хотел бы задать вопрос по-другому (спасибо за ваше терпение). Вот ссылка, на которую я ссылаюсь:
Как избежать дублирования логики на двух похожих WinForms?
OK. У меня есть диалог, который я создал. У нас есть элементы управления для пользовательского ввода, кнопки для отображения других диалогов (для получения другого ввода) и т. Д. Эстетически, я предпочитаю диалог с элементами управления, расположенными вертикально. Во всяком случае, я также думал о создании версии этого диалога UserControl. Этот UserControl будет иметь все те же элементы управления и ту же логику, но элементы управления будут размечены совершенно по-другому (больше по горизонтали, чем по вертикали).
Итак, я не могу просто создать еще один (третий) UserControl, который я перетаскиваю в оригинальной форме и в UserControl, который я хочу создать. (Этот третий UserControl будет содержать всю логику - таким образом, разделяя между ними) Я не могу сделать это из-за разных макетов.
У меня нет проблем с созданием двух (Form, UserControl), с элементами управления, расположенными по-разному, но я не хочу «вырезать и вставить» всю логику из одного в другой.
Это не похоже на случай с MVP или MVC. Моя модель - это сам диалог. Диалог инициализируется с некоторыми значениями, да, но после инициализации «Модель» становится дополнительным пользовательским вводом (который я затем беру, когда они нажимают кнопку ОК).
Возьмем, к примеру, этот код (событие для одной из моих кнопок в этом диалоговом окне):
private void EditQuery_Click(object sender, EventArgs e)
{
try
{
EditQueryParameters();
}
catch (System.Exception ex)
{
// TODO: Write ErrMsg to Log file.
MessageBox.Show("Edit Query Parameters Error:\n\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void EditQueryParameters()
{
if (m_ReportType.QueryScoreDetails && optPickDetail.Checked)
{
// This brings up a different type of dialog
QueryDetails();
return;
}
// DateRange, StartDate, and EndDate are all saved from the last time
// I called this dialog
DateType DtType = new DateType(m_ReportType.DBDateRangeField,
m_DateRange, m_StartDate, m_EndDate);
// StartTime, EndTime too!
TimeType TmType = new TimeType(m_ReportType.DBTimeRangeField,
m_StartTime, m_EndTime);
List<AdvancedFilter> Filters = null;
if (lstAdvancedQuery.Items.Count > 0)
{
Filters = new List<AdvancedFilter>();
}
for (int i = 0; i < lstAdvancedQuery.Items.Count; ++i)
{
Filters.Add((AdvancedFilter)lstAdvancedQuery.Items[i]);
}
// QueryType is also saved from the last time I called QueryBuilder
QueryBuilder QryBuilder = new QueryBuilder(m_ReportType.DBCatalog, m_ReportType.DBTable,
m_QueryType, ref DtType, ref TmType, ref Filters);
// I am using Visual WebGUI, I have to do it this way
QryBuilder.Closed += new EventHandler(QryBuilder_Closed);
QryBuilder.ShowDialog();
}
Я имею в виду, я полагаю, у меня мог бы быть некоторый "логический" класс, который выставляет что-то вроде:
public void EditQueryParameters(ref ReportType RptType, bool PickDetail,
string DateRange, DateTime StartDate, DateTime EndDate,
DateTime StartTime, DateTime EndTime, string QueryType)
{
if (ReportType.QueryScoreDetails && PickDetail)
{
// This brings up a different type of dialog
QueryDetails();
return;
}
DateType DtType = new DateType(ReportType.DBDateRangeField,
DateRange, StartDate, EndDate);
TimeType TmType = new TimeType(ReportType.DBTimeRangeField,
StartTime, EndTime);
// Yikes, more stuff to add to the signature of my method
// Will have to pull this outside the method and pass in Filters
List<AdvancedFilter> Filters = null;
if (lstAdvancedQuery.Items.Count > 0)
{
Filters = new List<AdvancedFilter>();
}
for (int i = 0; i < lstAdvancedQuery.Items.Count; ++i)
{
Filters.Add((AdvancedFilter)lstAdvancedQuery.Items[i]);
}
// QueryType is also saved from the last time I called QueryBuilder
QueryBuilder QryBuilder = new QueryBuilder(ReportType.DBCatalog, ReportType.DBTable,
QueryType, ref DtType, ref TmType, ref Filters);
// I am using Visual WebGUI, I have to do it this way
QryBuilder.Closed += new EventHandler(QryBuilder_Closed);
QryBuilder.ShowDialog();
}
Существует множество настроек для использования этого метода. Я не знаю, может быть, я ищу что-то еще .. "пятно"?
Кроме того, посмотрите на некоторые (не все) моего кода инициализации (он вызывается из constructor или form_Load; кажется, не стоит добавлять это в класс логики, так что это все еще "вырезано и вставить "между двумя):
private void InitializeUserDefinedTitle()
{
txtUserTitle.Text = m_UserTitle;
}
private void InitializePrintSelectionCriteria()
{
// Print Selection Criteria
chkSelectionCriteria.Checked = m_printSelectionCriteria;
}
private void InitializeTrendBy()
{
cmbTrend.Items.AddRange(Enum.GetNames(typeof(TrendBy)));
cmbTrend.SelectedIndex = (int)m_TrendBy;
cmbTrend.Visible = m_ReportType.TrendVisible;
lblTrend.Visible = m_ReportType.TrendVisible;
}
В итоге, исходная WinForm - это диалоговое окно, которое инициализировано данными (конструктор), отображается пользователю для ввода, когда они подтверждают диалог, в котором данные извлекаются (и эти данные хранятся вне диалогового окна, в элементе переменные, в следующий раз они вызывают диалог - это потому, что мы хотим показать, что они в последний раз выбирали / вводили).
Этот тип диалога, который я только что описал, также будет пользовательским элементом управления, и логика должна быть разделена между ними.
Спасибо.