#region Copyright Notice /* * gitter - VCS repository management tool * Copyright (C) 2014 Popovskiy Maxim Vladimirovitch <[email protected]> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #endregion namespace gitter.Controls { using System; using System.Collections.Generic; using System.Windows.Forms; using gitter.Framework; using gitter.Framework.Controls; using Resources = gitter.Properties.Resources; public abstract class PickerDialog<TPicker, TValue> : DialogBase, IExecutableDialog where TPicker : Control, IPicker<TValue>, new() where TValue : class { #region Data private Dictionary<TValue, Control> _controlCache; private Control _selectedControl; private Label _label; private TPicker _picker; #endregion #region .ctor protected PickerDialog(string displayName) { _controlCache = new Dictionary<TValue, Control>(); _label = new Label(); _picker = new TPicker(); SuspendLayout(); // // _label // _label.Name = "_label"; _label.AutoSize = true; _label.Bounds = new System.Drawing.Rectangle(0, 6, 54, 15); _label.Text = displayName; // // _picker // _picker.Name = "_picker"; _picker.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; _picker.Bounds = new System.Drawing.Rectangle(94, 3, 303, 23); _picker.TabIndex = 0; _picker.SelectedValueChanged += OnSelectedValueChanged; // // PickerDialog // AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); Controls.Add(_label); Controls.Add(_picker); Size = new System.Drawing.Size(400, 30); ResumeLayout(false); PerformLayout(); } #endregion #region Properties public TValue SelectedValue { get { return _picker.SelectedValue; } } protected virtual int MinimumSelectableItems { get { return 1; } } protected Control SelectedControl { get { return _selectedControl; } } #endregion #region Methods protected abstract void LoadItems(TPicker picker); protected abstract Control CreateControl(TValue item); protected override void OnLoad(EventArgs e) { base.OnLoad(e); LoadItems(_picker); if(_picker.DropDownItems.Count != 0) { var item = _picker.DropDownItems[0]; item.IsSelected = true; item.Activate(); if(_picker.DropDownItems.Count < MinimumSelectableItems) { _picker.Enabled = false; } } else { _picker.Enabled = false; _label.Enabled = false; } } protected Control GetOrCreateControl(TValue item) { Control control; if(!_controlCache.TryGetValue(item, out control)) { control = CreateControl(item); _controlCache.Add(item, control); } return control; } private void OnSelectedValueChanged(object sender, EventArgs e) { var item = _picker.SelectedValue; if(item == null) { return; } var control = GetOrCreateControl(item); int d = 0; if(_selectedControl != null) { d -= _selectedControl.Height; _selectedControl.Parent = null; _selectedControl = null; d -= 3; } _selectedControl = control; if(_selectedControl != null) { d += _selectedControl.Height; d += 3; } Height += d; if(_selectedControl != null) { _selectedControl.SetBounds(0, _picker.Bottom + 3, Width, 0, BoundsSpecified.X | BoundsSpecified.Y | BoundsSpecified.Width); _selectedControl.Parent = this; } } /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if(disposing) { if(_controlCache != null) { foreach(var ctl in _controlCache.Values) { if(ctl != null && !ctl.IsDisposed) { ctl.Dispose(); } } _controlCache.Clear(); } } base.Dispose(disposing); } #endregion #region IExecutableDialog Members public virtual bool Execute() { if(_selectedControl != null) { var ctl = _selectedControl as IExecutableDialog; if(ctl != null) { if(!ctl.Execute()) { return false; } } } return true; } #endregion } }