|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThe WinForms Probably because of the popup nature, BackgroundTo show // namespace System
public interface IServiceProvider
{
object GetService(Type serviceType);
}
// namespace System.Windows.Forms.Design
public interface IWindowsFormsEditorService
{
void CloseDropDown();
void DropDownControl(Control control);
DialogResult ShowDialog(Form dialog);
}
// namespace System.Drawing.Design
public class ColorEditor : UITypeEditor
{
public ColorEditor();
// Methods
public override object EditValue(ITypeDescriptorContext context,
IServiceProvider provider, object value);
// Nested Types
private class ColorUI : Control {}
private class ColorPalette : Control {}
private class CustomColorDialog : ColorDialog {}
}
When invoking
Scratched your head twice? Reading Implementing IWindowsFormsEditorService Interface (last section) did help my understanding.
private class ColorUI : Control
{
public ColorUI(ColorEditor editor);
// Methods
public void Start(IWindowsFormsEditorService edSvc, object value);
public void End();
// Properties
public object Value { get; }
// Fields
private IWindowsFormsEditorService edSvc;
// Nested Types
private class ColorEditorTabControl : TabControl {}
private class ColorEditorListBox : ListBox {}
}
Once we receive the Control colorUI;
TabControl tab = (TabControl)colorUI.Controls[0];
Control palette = tab.TabPages[0].Controls[0];
ListBox lbCommon = (ListBox)tab.TabPages[1].Controls[0];
ListBox lbSystem = (ListBox)tab.TabPages[2].Controls[0];
I used here the WinForms internal naming. The palette control is on the first tab page (US-English: "Custom"), and the common listbox shows the web colors. Note, that we can add here our own tabpages too. The hackAs stated above, the drop-down operation requires that the To achieve our goals, we must overcome four problems:
ocColorEditorTo make it a fully functional user control, there was a lot more coding necessary that I won't cover here. To help in understanding the main operation, here is a skeleton of the // namespace OC.Windows.Forms
public class ocColorEditor : UserControl
{
public event EventHandler ColorChanged
public ocColorEditor() : base()
private ColorEditorService service;
protected ColorEditor editor;
protected Control colorUI;
public Color Color { get; set; }
public Color[] CustomColors { get; set; }
public void ShowEditor()
{
service = new ColorEditorService();
editor = new ColorEditor();
editor.EditValue(service, _Color);
// restore EditorService reference
}
public void CloseEditor()
{
service.CloseDropDownInternal();
// send return key
}
private void service_ColorUIAvailable(object sender,
EditorServiceEventArgs e)
{
if (e.ColorUI != null)
{
// ColorUI ready to show or new Color set
if (colorUI == null)
{
// show ColorUI
colorUI = e.ColorUI;
Controls.Add(colorUI);
// set CustomColors
}
}
else
{
// ColorUI ready to close
colorUI = null;
service = null;
}
}
private void service_ColorChanged(object sender, EventArgs e)
{
// get selected color value
// test if custom colors were modified
// deselect former selected color
ColorChanged(this, EventArgs.Empty);
}
private class ColorEditorService : IServiceProvider,
IWindowsFormsEditorService
{
public event EventHandler<EditorServiceEventArgs>
ColorUIAvailable
public event EventHandler ColorChanged
private bool closeEditor;
public void CloseDropDownInternal()
{
closeEditor = true;
}
// IServiceProvider Members
public object GetService(Type serviceType)
{
return this;
}
// IWindowsFormsEditorService Members
public void DropDownControl(Control control)
{
ColorUIAvailable(this,
new EditorServiceEventArgs(control));
}
public void CloseDropDown()
{
if (!closeEditor)
// user selected color
ColorChanged(this, EventArgs.Empty);
else
// close editor
ColorUIAvailable(this,
new EditorServiceEventArgs(null));
}
public DialogResult ShowDialog(Form dialog)
{
throw new Exception("Not implemented");
}
}
private class EditorServiceEventArgs : EventArgs
}
Instancing UserControl size
Tab key operationThe Tab key wraps and confines the selection to the editor's tabpages. This is proper behaviour for a popup component, but is annoying now with other controls present on the form. To allow tabbing out ( Custom colorsI usually preload custom colors with all non-default application colors, so I took some lengths to ensure that this is possible with the editor already running. This, again, requires 'black magic' to manipulate a private field. Given the way I learned to right-click on a custom color (I wondered what a customized Using the codeThe download contains a demo project I used for developing and testing. A Points of interestYou guessed it by now, there is credit due: without Lutz Roeder's .NET Reflector, this article (as many others) would never have come into existence. Two future articles will describe how to replace the palette color area in a customized
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||