Click here to Skip to main content
15,893,508 members
Articles / Desktop Programming / Windows Forms

Controls Library: Extended ListView with Column Mapping

Rate me:
Please Sign up or sign in to vote.
4.86/5 (29 votes)
27 Mar 2014CPOL5 min read 83K   7.6K   110  
Docking windows container, extended listview, extended property editor.
using dwf.tool;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace dwf.gui
{

    public class FieldsEditor : UserControl, IDockContent, IPicture
    {
        private string lockName = "FieldsEditor";
        private AccessEditor access;
        private PList list;
        private PList fields;
        private ToolStrip tools;
        private ToolStripButton toolGroup;
        private ToolStripButton toolSort;
        private ToolStripButton toolCut;
        private ToolStripButton toolRefresh;
        private ToolStripButton toolSave;
        private ToolStripButton toolAccess;
        private ToolStripButton toolLog;
        private ToolStripDropDownButton toolAdd;
        private ToolStripSplitButton toolStatus;
        private ToolStripButton toolStatusNew;
        private ToolStripButton toolStatusActual;
        private ToolStripButton toolStatusDelete;
        private ToolStripButton toolStatusArchive;
        private ToolStripButton toolStatusEdit;
        private ToolStripButton toolStatusError;
        private ToolStripButton toolRemove;
        private ToolStripSeparator toolSep;
        private ToolStripButton toolEdit;
        private SplitContainer container;

        private ToolWindow addToolForm;
        private EventHandler<FieldsEditorEventArg> _handleItemSelect;
        private FieldsEditorEventArg _cacheArg = new FieldsEditorEventArg();
        private PListGetEditorDelegate _handleGetCellEditor;
        private PListGetEditorDelegate _cacheHandleGetEditor;
        private object _source;
        private DockType dockType = DockType.Right;


        public FieldsEditor()
            : this(new PList())
        {
        }

        public FieldsEditor(PList fields)
            : base()
        {
            _cacheHandleGetEditor = new PListGetEditorDelegate(ListOnGetCellEditor);

            this.list = fields;
            this.list.EditMode = EditModes.ByClick;
            this.list.RetriveCellEditor += _cacheHandleGetEditor;
            this.list.SelectionChanged += ListSelectionChanged;

            InitializeControl();

            this.toolStatusActual.Tag = DBStatus.Actual;
            this.toolStatusArchive.Tag = DBStatus.Archive;
            this.toolStatusEdit.Tag = DBStatus.Edit;
            this.toolStatusError.Tag = DBStatus.Error;
            this.toolStatusDelete.Tag = DBStatus.Delete;
            this.toolStatusNew.Tag = DBStatus.New;

            this.fields = new PList();
            this.fields.Width = 400;
            this.fields.Height = 300;
            this.fields.EditMode = EditModes.ByClick;
            this.fields.RetriveCellEditor += _cacheHandleGetEditor;

            this.addToolForm = new ToolWindow();
            this.addToolForm.Target = this.fields;
            this.addToolForm.Mode = ToolShowMode.Dialog;
            this.addToolForm.ButtonAccept.Click += new EventHandler(AddToolFormOnAcceptClick);

            Localizing();
        }

        public PList List
        {
            get { return list; }
        }

        protected override void Dispose(bool disposing)
        {
            if (addToolForm != null)
                addToolForm.Dispose();
            if (fields != null)
                fields.Dispose();
            base.Dispose(disposing);
        }

        private void CheckStatus()
        {
            IStatus status = _source as IStatus;
            if (status != null)
            {
                ToolStripItem item = null;
                if (status.Status == DBStatus.Actual)
                    item = toolStatusActual;
                else if (status.Status == DBStatus.Archive)
                    item = toolStatusArchive;
                else if (status.Status == DBStatus.Delete)
                    item = toolStatusDelete;
                else if (status.Status == DBStatus.Edit)
                    item = toolStatusEdit;
                else if (status.Status == DBStatus.Error)
                    item = toolStatusError;
                else if (status.Status == DBStatus.New)
                    item = toolStatusNew;
                if (item != null)
                {
                    toolStatus.Image = item.Image;
                    toolStatus.Text = item.Text;
                }
            }
        }

        private void ListSelectionChanged(object sender, EventArgs e)
        {
            if (list.Mode == PListMode.List && GuiService.Main != null && list.SelectedItem != null)
                GuiService.Main.ShowProperty(this, list.SelectedItem, true);
            //GuiService;
        }


        public object DataSource
        {
            get { return _source; }
            set
            {
                if (_source == value)
                    return;

                if (_source is INotifyPropertyChanged)
                    ((INotifyPropertyChanged)_source).PropertyChanged -= OnDataPropertyChanged;

                _source = value;

                if (_source is INotifyPropertyChanged)
                    ((INotifyPropertyChanged)_source).PropertyChanged += OnDataPropertyChanged;

                Type type = _source == null ? null : _source.GetType();

                if (_source is IList)
                {
                    list.Mode = PListMode.List;
                    if (_source is IListQuery)
                    {
                        type = typeof(dwf.tool.ListExtendView<>);
                        Type typeItem = type.MakeGenericType(((IListQuery)_source).ItemType);
                        list.ListSource = (IList)ReflectionAccessor.CreateObject(typeItem, new Type[] { typeof(IList) }, new object[] { _source }, true);
                    }
                    else
                        list.ListSource = (IList)_source;
                    type = list.ListType;
                }
                else
                {
                    list.Mode = PListMode.Fields;
                    list.FieldSource = _source;
                }

                bool flag = list.Mode == PListMode.List;
                this.toolAdd.Visible = flag;
                this.toolRemove.Visible = flag;
                this.toolEdit.Visible = flag;
                this.toolSep.Visible = flag;
                this.toolLog.Visible = LogClick != null;
                flag = type != null && TypeService.IsInterface(type, "IEditable");
                this.toolRefresh.Visible = flag;
                this.toolSave.Visible = flag;

                flag = type != null && TypeService.IsInterface(type, "IStatus");
                this.toolStatus.Visible = flag;

                if (value is IEditable)
                {
                    this.toolSave.Enabled = ((IEditable)value).IsChanged;
                }
                CheckStatus();

                if (value is IFSerialize)
                {
                    this.toolSave.Visible = true;
                    this.toolSave.Enabled = true;
                }
                toolAccess.Visible = value is IAccessable;
                ViewAccess(toolAccess.Checked);
            }
        }

        private void OnDataPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            IEditable ediable = list.FieldSource as IEditable;
            if (ediable != null)
            {
                GuiService.Context.Post((object parameter) =>
                {
                    toolSave.Enabled = ((IEditable)parameter).IsChanged;
                    CheckStatus();
                }, ediable);
            }
        }

        Image IPicture.Image
        {
            get { return Localize.GetImage("pencil"); }
        }

        public event EventHandler<FieldsEditorEventArg> ItemSelect
        {
            add { _handleItemSelect += value; }
            remove { _handleItemSelect -= value; }
        }

        public event PListGetEditorDelegate GetCellEditor
        {
            add { _handleGetCellEditor += value; }
            remove { _handleGetCellEditor -= value; }
        }

        private IPCellEditor ListOnGetCellEditor(object sender, object listItem, object itemValue, IPCell cell)
        {
            if (_handleGetCellEditor != null)
                return _handleGetCellEditor(sender, listItem, itemValue, cell);
            else
                return null;
        }

        public PList Fields
        {
            get { return list; }
            set
            {
                if (value == list)
                    return;
                Controls.Remove(list);
                list = value;
                list.Visible = true;
                list.Dock = DockStyle.Fill;
                Controls.Add(list);
                list.BringToFront();
            }
        }

        public ToolStrip Tools
        {
            get { return tools; }
        }

        public bool ReadOnly
        {
            get { return list.ReadOnly; }
            set
            {
                if (value)
                {
                    list.EditState = EditListState.ReadOnly;
                }
                else
                {
                    list.EditState = EditListState.Edit;
                }
                list.ReadOnly = value;
                toolCut.Enabled = !value;
                toolSave.Visible = !value;
                toolAdd.Enabled = !value;
                toolRemove.Enabled = !value;
                toolEdit.Enabled = !value;
            }
        }

        public static event EventHandler<FieldsEditorEventArg> StatusClick;

        private void ToolStatusClick(object sender, EventArgs e)
        {
            if (StatusClick != null)
                StatusClick(this, new FieldsEditorEventArg() { Item = DataSource });
        }

        public event EventHandler Saved;

        private void ToolSaveClick(object sender, EventArgs e)
        {
            list.CurrentCell = null;
            if (Saved != null)
            {
                Saved(this, new FieldsEditorEventArg() { Item = DataSource });
            }
            else if (DataSource is IFSerialize)
            {
                Environment.CurrentDirectory = System.IO.Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
                ((IFSerialize)DataSource).SaveDirectory(Environment.CurrentDirectory);
            }
            else if (DataSource is IEditable)
            {
                ((IEditable)DataSource).Save();
            }
        }

        private void ToolCutClick(object sender, EventArgs e)
        {
            if (list.CurrentCell == null)
                return;
            list.SetNull(list.SelectedItem as Field);
        }

        public static event EventHandler<FieldsEditorEventArg> LogClick;

        private void ToolLogClick(object sender, EventArgs e)
        {
            if (LogClick != null && list.Mode == PListMode.Fields)
                LogClick(this, new FieldsEditorEventArg() { Item = DataSource });
        }

        private void ToolAccessClick(object sender, EventArgs e)
        {
            toolAccess.Checked = !toolAccess.Checked;
            ViewAccess(toolAccess.Checked);
        }

        private void ViewAccess(bool flag)
        {
            if (DataSource is IAccessable && ((IAccessable)DataSource).Access != null && flag)
            {
                this.access.Access = ((IAccessable)DataSource).Access;
                container.Panel2Collapsed = false;
            }
            else
            {
                container.Panel2Collapsed = true;
            }
        }

        private void ToolRefreshClick(object sender, EventArgs e)
        {
            if (DataSource is IEditable)
            {
                list.CurrentCell = null;
                ((IEditable)DataSource).Reject();
                ((IEditable)DataSource).Refresh();
            }
        }

        public void ToolSortClick(object sender, EventArgs e)
        {
            list.ListInfo.Sorting.Clear();
            if (!toolSort.Checked)
                list.OnColumnSort("Order", ListSortDirection.Ascending);
            else
                list.OnColumnSort("ToString", ListSortDirection.Ascending);
        }

        public void ToolGroupClick(object sender, EventArgs e)
        {
            if (list.Mode == PListMode.Fields)
                list.Grouping = toolGroup.Checked;
            else if (list.Mode == PListMode.List)
                list.OnTreeMode(toolGroup.Checked);
        }

        private void AddToolFormOnAcceptClick(object sender, EventArgs e)
        {
            if (list.ListSource == null)
                return;
            list.ItemAdd(fields.FieldSource);
            //addToolForm.Close ();
        }

        private void ToolRemoveOnClick(object sender, EventArgs e)
        {
            if (list.Selection.Count == 0 || list.Mode != PListMode.List)
                return;
            for (int i = 0; i < list.Selection.Count; i++)
            {
                object o = list.Selection[i].Item;
                list.ItemRemove(o);

                if (list.ListSource != _source)
                    ((IList)_source).Remove(o);
                i--;
            }
            list.QueueDraw(true, true);
        }

        private void ToolAddOnClick(object sender, EventArgs e)
        {
            if (list.ListSource == null || list.Mode != PListMode.List)
                return;
            object newObject = list.ItemNew();
            fields.FieldSource = newObject;
            addToolForm.ButtonAccept.Enabled = true;
            addToolForm.Label.Text = toolAdd.Text;

            addToolForm.Show(tools, new Point(tools.Bounds.X, tools.Bounds.Bottom));
        }

        private void ToolEditOnClick(object sender, EventArgs e)
        {
            OnItemSelect(_cacheArg);
        }

        public void OnItemSelect(FieldsEditorEventArg ea)
        {
            if (list.SelectedItem == null || list.Mode != PListMode.List)
                return;
            ea.Cancel = false;
            ea.Item = list.SelectedItem;
            if (_handleItemSelect != null)
            {
                _handleItemSelect(this, ea);
            }
            if (ea.Cancel)
                return;
            addToolForm.ButtonAccept.Enabled = false;
            addToolForm.Label.Text = toolEdit.Text;

            fields.FieldSource = list.SelectedItem;
            addToolForm.Show(tools, new Point(toolAdd.Bounds.X, toolAdd.Bounds.Bottom));
        }

        private void ListOnCellDoubleClick(object sender, PListHitTestEventArgs e)
        {
            OnItemSelect(_cacheArg);
        }

        private void ListOnSelectionChanged(object sender, EventArgs e)
        {
            ShowProperty();
        }

        private void ListOnCellMouseChanged(object sender, EventArgs e)
        {
            ShowProperty();
        }

        private void ToolStatusItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            IStatus status = _source as IStatus;
            if (status != null)
            {
                status.Status = (DBStatus)e.ClickedItem.Tag;
                CheckStatus();
            }
        }

        private void ShowProperty()
        {
            if (GuiService.Main != null && list.SelectedItem != null)
                GuiService.Main.ShowProperty(this, list.SelectedItem, true);
        }

        #region IDockMain implementation
        public DockType DockType
        {
            get { return dockType; }
            set { dockType = value; }
        }

        public void Localizing()
        {
            GuiService.Init();
            this.Text = Localize.Get(lockName, "Property Editor");
            this.toolSort.Text = Localize.Get(lockName, "Sort");
            this.toolSort.Image = Localize.GetImage(lockName, "Sort");
            this.toolGroup.Text = Localize.Get(lockName, "Group");
            this.toolGroup.Image = Localize.GetImage(lockName, "Group");
            this.toolRefresh.Text = Localize.Get(lockName, "Refresh");
            this.toolRefresh.Image = Localize.GetImage(lockName, "Refresh");
            this.toolCut.Text = Localize.Get(lockName, "Clear");
            this.toolCut.Image = Localize.GetImage(lockName, "Clear");
            this.toolSave.Text = Localize.Get(lockName, "Save");
            this.toolSave.Image = Localize.GetImage(lockName, "Save");
            this.toolAdd.Text = Localize.Get(lockName, "Add");
            this.toolAdd.Image = Localize.GetImage(lockName, "Add");
            this.toolRemove.Text = Localize.Get(lockName, "Delete");
            this.toolRemove.Image = Localize.GetImage(lockName, "Delete");
            this.toolEdit.Text = Localize.Get(lockName, "Edit");
            this.toolEdit.Image = Localize.GetImage(lockName, "Edit");
            this.toolStatus.Text = Localize.Get(lockName, "Actual");
            this.toolStatus.Image = Localize.GetImage(lockName, "Actual");
            this.toolStatusActual.Text = Localize.Get(lockName, "Actual");
            this.toolStatusActual.Image = Localize.GetImage(lockName, "Actual");
            this.toolStatusArchive.Text = Localize.Get(lockName, "Archive");
            this.toolStatusArchive.Image = Localize.GetImage(lockName, "Archive");
            this.toolStatusEdit.Text = Localize.Get(lockName, "Edited");
            this.toolStatusEdit.Image = Localize.GetImage(lockName, "Edited");
            this.toolStatusError.Text = Localize.Get(lockName, "Error");
            this.toolStatusError.Image = Localize.GetImage(lockName, "Error");
            this.toolStatusNew.Text = Localize.Get(lockName, "New");
            this.toolStatusNew.Image = Localize.GetImage(lockName, "New");
            this.toolStatusDelete.Text = Localize.Get(lockName, "Deleted");
            this.toolStatusDelete.Image = Localize.GetImage(lockName, "Deleted");
            this.toolAccess.Text = Localize.Get(lockName, "Access");
            this.toolAccess.Image = Localize.GetImage(lockName, "Access");
            this.toolLog.Text = Localize.Get(lockName, "Log");
            this.toolLog.Image = Localize.GetImage(lockName, "Log");
            this.Text = Localize.Get(lockName, "Editor");

            if (fields != null)
                fields.Localizing();

            list.Localizing();
        }

        public bool HideOnClose
        {
            get { return true; }
        }

        #endregion
        public void InitializeControl()
        {
            this.tools = new ToolStrip();
            this.toolGroup = new ToolStripButton();
            this.toolSort = new ToolStripButton();
            this.toolRefresh = new ToolStripButton();
            this.toolCut = new ToolStripButton();
            this.toolSave = new ToolStripButton();
            this.toolAdd = new ToolStripDropDownButton();
            this.toolRemove = new ToolStripButton();
            this.toolEdit = new ToolStripButton();
            this.toolAccess = new ToolStripButton();
            this.toolLog = new ToolStripButton();
            this.toolSep = new ToolStripSeparator();
            this.toolStatus = new ToolStripSplitButton();
            this.toolStatusActual = new ToolStripButton();
            this.toolStatusArchive = new ToolStripButton();
            this.toolStatusEdit = new ToolStripButton();
            this.toolStatusError = new ToolStripButton();
            this.toolStatusDelete = new ToolStripButton();
            this.toolStatusNew = new ToolStripButton();
            this.container = new SplitContainer();
            this.access = new AccessEditor();
            this.SuspendLayout();

            //this.toolStatus.Alignment = ToolStripItemAlignment.Right;
            this.toolStatus.DropDownItems.AddRange(new ToolStripItem[]{
                this.toolStatusNew,
                this.toolStatusActual,
                this.toolStatusEdit,
                this.toolStatusArchive,
                this.toolStatusError,
                this.toolStatusDelete});
            this.toolStatus.DisplayStyle = ToolStripItemDisplayStyle.Image;
            this.toolStatus.ButtonClick += ToolStatusClick;
            this.toolStatus.DropDownItemClicked += ToolStatusItemClicked;
            //
            this.toolStatusArchive.Name = "toolStatusArchive";
            //
            this.toolStatusEdit.Name = "toolStatusEdit";
            //
            this.toolStatusError.Name = "toolStatusError";
            //
            this.toolStatusDelete.Name = "toolStatusDelete";
            this.toolStatusDelete.Enabled = false;
            //
            this.toolStatusActual.Name = "toolStatusActual";
            this.toolStatusActual.Enabled = false;
            //
            this.toolStatusNew.Name = "toolStatusNew";
            this.toolStatusNew.Enabled = false;
            //
            this.tools.Name = "tools";
            this.tools.Dock = DockStyle.Top;
            this.tools.GripStyle = ToolStripGripStyle.Hidden;
            this.tools.ImageScalingSize = new System.Drawing.Size(22, 22);
            this.tools.Items.AddRange(new ToolStripItem[]{             
                this.toolStatus,
                this.toolGroup, 
                this.toolSort,
                this.toolCut,             
                this.toolRefresh,
                this.toolSave,
                this.toolLog,
                this.toolAccess,
                this.toolAdd, 
                this.toolRemove, 
                this.toolEdit,
                this.toolSep               
            });

            this.toolSort.Name = "toolSort";
            this.toolSort.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;

            this.toolSort.CheckOnClick = true;
            this.toolSort.Click += new System.EventHandler(this.ToolSortClick);

            this.toolGroup.Name = "toolGroup";
            this.toolGroup.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;

            this.toolGroup.CheckOnClick = true;
            this.toolGroup.Click += new System.EventHandler(this.ToolGroupClick);

            this.toolCut.Name = "toolCut";
            this.toolCut.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
            this.toolCut.Click += new System.EventHandler(this.ToolCutClick);
            this.toolCut.Visible = false;

            this.toolLog.Name = "toolLog";
            this.toolLog.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
            this.toolLog.Click += new System.EventHandler(this.ToolLogClick);

            this.toolAccess.Name = "toolAccess";
            this.toolAccess.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
            this.toolAccess.Click += new System.EventHandler(this.ToolAccessClick);
            //this.toolAccess.Checked = true;

            this.toolRefresh.Name = "toolRefresh";
            this.toolRefresh.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
            this.toolRefresh.Click += new System.EventHandler(this.ToolRefreshClick);

            this.toolSave.Name = "toolSave";
            this.toolSave.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
            this.toolSave.Click += new System.EventHandler(this.ToolSaveClick);

            this.toolAdd.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
            this.toolAdd.Name = "toolAdd";
            this.toolAdd.Click += new System.EventHandler(this.ToolAddOnClick);

            this.toolRemove.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
            this.toolRemove.Name = "toolRemove";
            this.toolRemove.Click += new System.EventHandler(this.ToolRemoveOnClick);

            this.toolEdit.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
            this.toolEdit.Name = "toolEdit";
            this.toolEdit.Click += new System.EventHandler(this.ToolEditOnClick);


            this.list.Name = "fields";
            this.list.Dock = DockStyle.Fill;

            this.access.Name = "access";
            this.access.Dock = DockStyle.Fill;

            this.container.Panel1.Controls.AddRange(new Control[] { list, tools });
            this.container.Panel2.Controls.AddRange(new Control[] { access });
            this.container.Orientation = Orientation.Horizontal;
            this.container.Name = "container";
            this.container.Dock = DockStyle.Fill;
            this.container.Panel2Collapsed = true;

            this.Controls.Add(container);
            this.ResumeLayout();

        }
    }

    public class ParamsChangedArg : EventArgs
    {
        protected SortedList<Field, object> _values;

        public ParamsChangedArg(SortedList<Field, object> values)
            : base()
        {
            _values = values;
        }

        public SortedList<Field, object> Values
        {
            get { return _values; }
        }

    }

    public class FieldsEditorEventArg : CancelEventArgs
    {
        object item;

        public FieldsEditorEventArg()
            : base()
        {
        }

        public object Item
        {
            get { return item; }
            set { item = value; }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Kazakstan Kazakstan
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions