첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

■ RepositoryItemTokenEdit 클래스 사용하기

------------------------------------------------------------------------------------------------------------------------


TestProject.zip


RepositoryItemCustomTokenEdit.cs

 

 

using DevExpress.XtraEditors.Drawing;

using DevExpress.XtraEditors.Registrator;

using DevExpress.XtraEditors.Repository;

using DevExpress.XtraEditors.ViewInfo;

 

namespace TestProject

{

    /// <summary>

    /// 저장소 항목 커스텀 토큰 에디터

    /// </summary>

    [UserRepositoryItem("RegisterCustomTokenEdit")]

    public class RepositoryItemCustomTokenEdit : RepositoryItemTokenEdit

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region Field

 

        /// <summary>

        /// 커스텀 에디터명

        /// </summary>

        public const string CustomEditName = "CustomTokenEdit";

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 에디터 타입명 - EditorTypeName

 

        /// <summary>

        /// 에디터 타입명

        /// </summary>

        public override string EditorTypeName

        {

            get

            {

                return CustomEditName;

            }

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Static

 

        #region 생성자 - RepositoryItemCustomTokenEdit()

 

        /// <summary>

        /// 생성자

        /// </summary>

        static RepositoryItemCustomTokenEdit()

        {

            RegisterCustomTokenEdit();

        }

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Instance

        //////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - RepositoryItemCustomTokenEdit()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public RepositoryItemCustomTokenEdit()

        {

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Public

 

        #region 커스텀 토큰 에디터 등록하기 - RegisterCustomTokenEdit()

 

        /// <summary>

        /// 커스텀 토큰 에디터 등록하기

        /// </summary>

        public static void RegisterCustomTokenEdit()

        {

            EditorRegistrationInfo.Default.Editors.Add

            (

                new EditorClassInfo

                (

                    CustomEditName,

                    typeof(CustomTokenEdit),

                    typeof(RepositoryItemCustomTokenEdit),

                    typeof(TokenEditViewInfo),

                    new TokenEditPainter(),

                    true,

                    null

                )

            );

        }

 

        #endregion

    }

}

 

 

CustomTokenEditPopupForm.cs

 

 

using System.Collections;

using System.Collections.Generic;

 

using DevExpress.XtraEditors;

using DevExpress.XtraEditors.Popup;

 

namespace TestProject

{

    /// <summary>

    /// 커스텀 토큰 에디터 팝업 폼

    /// </summary>

    public class CustomTokenEditPopupForm : TokenEditPopupForm

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - CustomTokenEditPopupForm(tokenEdit)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="tokenEdit">토큰 에디터</param>

        public CustomTokenEditPopupForm(TokenEdit tokenEdit) : base(tokenEdit)

        {

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

 

        #region 데이터 소스 구하기 - GetDataSource()

 

        /// <summary>

        /// 데이터 소스 구하기

        /// </summary>

        /// <returns>데이터 소스</returns>

        protected override IList GetDataSource()

        {

            TokenEditTokenCollection tokenEditTokenCollection = Properties.Tokens;

 

            TokenEditSelectedItemCollection tokenEditSelectedItemCollection = Properties.SelectedItems;

 

            List<TokenEditToken> list = new List<TokenEditToken>(Properties.Tokens.Count);

 

            for(int i = 0; i < tokenEditTokenCollection.Count; i++)

            {

                TokenEditToken tokenEditToken = tokenEditTokenCollection[i];

 

                if(IsSelected(tokenEditToken))

                {

                    ObjectWrapper objectWrapper = (ObjectWrapper)tokenEditToken.Value;

 

                    tokenEditToken = new TokenEditToken(tokenEditToken.Description, objectWrapper.Clone());

                }

 

                list.Add(tokenEditToken);

            }

 

            return list;

        }

 

        #endregion

        #region 선택 여부 구하기 - IsSelected(tokenEditToken)

 

        /// <summary>

        /// 선택 여부 구하기

        /// </summary>

        /// <param name="tokenEditToken">토큰 에디터 토큰</param>

        /// <returns>선택 여부</returns>

        protected bool IsSelected(TokenEditToken tokenEditToken)

        {

            foreach(TokenEditToken item in Properties.SelectedItems)

            {

                if(object.ReferenceEquals(tokenEditToken, item))

                {

                    return true;

                }

            }

 

            return false;

        }

 

        #endregion

    }

}

 

 

CustomTokenEdit.cs

 

 

using System.ComponentModel;

 

using DevExpress.XtraEditors;

using DevExpress.XtraEditors.Popup;

 

namespace TestProject

{

    /// <summary>

    /// 커스텀 토큰 에디터

    /// </summary>

    [ToolboxItem(true)]

    public class CustomTokenEdit : TokenEdit

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 속성 - Properties

 

        /// <summary>

        /// 속성

        /// </summary>

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]

        public new RepositoryItemCustomTokenEdit Properties

        {

            get

            {

                return base.Properties as RepositoryItemCustomTokenEdit;

            }

        }

 

        #endregion

        #region 에디터 타입명 - EditorTypeName

 

        /// <summary>

        /// 에디터 타입명

        /// </summary>

        public override string EditorTypeName

        {

            get

            {

                return RepositoryItemCustomTokenEdit.CustomEditName;

            }

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - CustomTokenEdit()

 

        /// <summary>

        /// 생성자

        /// </summary>

        static CustomTokenEdit()

        {

            RepositoryItemCustomTokenEdit.RegisterCustomTokenEdit();

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

 

        #region 팝업 폼 생성하기 - CreatePopupForm()

 

        /// <summary>

        /// 팝업 폼 생성하기

        /// </summary>

        /// <returns>토큰 에디터 팝업 폼</returns>

        protected override TokenEditPopupForm CreatePopupForm()

        {

            return new CustomTokenEditPopupForm(this);

        }

 

        #endregion

    }

}

 

 

Employee.cs

 

 

using System.Collections;

using System.Collections.Generic;

using System.ComponentModel;

 

namespace TestProject

{

    /// <summary>

    /// 직원

    /// </summary>

    public class Employee : INotifyPropertyChanged

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region 속성 변경시 - PropertyChanged

 

        /// <summary>

        /// 속성 변경시

        /// </summary>

        public event PropertyChangedEventHandler PropertyChanged;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// 성명

        /// </summary>

        private string name;

 

        /// <summary>

        /// 토큰 리스트

        /// </summary>

        private IList tokenList;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 성명 - Name

 

        /// <summary>

        /// 성명

        /// </summary>

        public string Name

        {

            get

            {

                return this.name;

            }

            set

            {

                if(this.name == value)

                {

                    return;

                }

 

                this.name = value;

 

                FirePropertyChangedEvent("Name");

            }

        }

 

        #endregion

        #region 토큰 리스트 - TokenList

 

        /// <summary>

        /// 토큰 리스트

        /// </summary>

        [Browsable(false)]

        public IList TokenList

        {

            get

            {

                return this.tokenList;

            }

            set

            {

                this.tokenList = value;

            }

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - Employee(name)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="name">성명</param>

        public Employee(string name)

        {

            this.name      = name;

            this.tokenList = new List<string>();

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 문자열 구하기 - ToString()

 

        /// <summary>

        /// 문자열 구하기

        /// </summary>

        /// <returns>문자열</returns>

        public override string ToString()

        {

            return this.name;

        }

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

 

        #region 속성 변경시 이벤트 발생시키기 - FirePropertyChangedEvent(propertyName)

 

        /// <summary>

        /// 속성 변경시 이벤트 발생시키기

        /// </summary>

        /// <param name="propertyName">속성명</param>

        protected virtual void FirePropertyChangedEvent(string propertyName)

        {

            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

        }

 

        #endregion

    }

}

 

 

ObjectWrapper.cs

 

 

using System;

 

namespace TestProject

{

    /// <summary>

    /// 오브젝트 래퍼

    /// </summary>

    public class ObjectWrapper : ICloneable

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// 소스

        /// </summary>

        private int source;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 소스 - Source

 

        /// <summary>

        /// 소스

        /// </summary>

        public int Source

        {

            get

            {

                return this.source;

            }

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - ObjectWrapper(source)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="source">소스</param>

        public ObjectWrapper(int source)

        {

            this.source = source;

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 문자열 구하기 - ToString()

 

        /// <summary>

        /// 문자열 구하기

        /// </summary>

        /// <returns>문자열</returns>

        public override string ToString()

        {

            return Source.ToString();

        }

 

        #endregion

        #region 복제하기 - Clone()

 

        /// <summary>

        /// 복제하기

        /// </summary>

        /// <returns>복제 객체</returns>

        public ObjectWrapper Clone()

        {

            return new ObjectWrapper(Source);

        }

 

        #endregion

        #region 복제하기 - ICloneable.Clone()

 

        /// <summary>

        /// 복제하기

        /// </summary>

        /// <returns>복제 객체</returns>

        object ICloneable.Clone()

        {

            return Clone();

        }

 

        #endregion

    }

}

 

 

MainForm.cs

 

 

using System.Collections;

using System.Collections.Generic;

using System.ComponentModel;

 

using DevExpress.Utils;

using DevExpress.XtraEditors;

using DevExpress.XtraGrid.Columns;

using DevExpress.XtraGrid.Views.Base;

using DevExpress.XtraGrid.Views.Grid;

 

namespace TestProject

{

    /// <summary>

    /// 메인 폼

    /// </summary>

    public partial class MainForm : XtraForm

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// 업데이트 여부

        /// </summary>

        private bool update = false;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - MainForm()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MainForm()

        {

            InitializeComponent();

 

            #region 그리드 컨트롤을 설정한다.

 

            this.gridView.OptionsDetail.EnableMasterViewMode = false;

            this.gridView.OptionsSelection.MultiSelect       = true;

            this.gridView.OptionsSelection.MultiSelectMode   = GridMultiSelectMode.CellSelect;

            this.gridView.FocusRectStyle                     = DrawFocusRectStyle.CellFocus;

 

            this.gridView.OptionsView.ShowGroupPanel = false;

 

            this.gridView.IndicatorWidth                         = 30;

            this.gridView.OptionsView.ShowIndicator              = true;

            this.gridView.OptionsView.EnableAppearanceEvenRow    = false;

            this.gridView.OptionsView.EnableAppearanceOddRow     = false;

            this.gridView.OptionsBehavior.KeepFocusedRowOnUpdate = false;

            this.gridView.OptionsNavigation.AutoFocusNewRow      = true;

 

            this.gridView.OptionsBehavior.AutoPopulateColumns      = false;

            this.gridView.OptionsView.ShowColumnHeaders            = true;

            this.gridView.OptionsView.ColumnAutoWidth              = false;

            this.gridView.OptionsMenu.EnableColumnMenu             = false;

            this.gridView.OptionsNavigation.EnterMoveNextColumn    = true;

            this.gridView.OptionsCustomization.AllowColumnMoving   = false;

            this.gridView.OptionsCustomization.AllowColumnResizing = true;

            this.gridView.OptionsCustomization.AllowFilter         = false;

            this.gridView.OptionsCustomization.AllowSort           = false;

 

            this.gridView.OptionsView.ShowButtonMode                   = ShowButtonModeEnum.ShowForFocusedCell;

            this.gridView.OptionsView.AllowCellMerge                   = false;

            this.gridView.OptionsBehavior.EditorShowMode               = EditorShowMode.Default;

            this.gridView.OptionsBehavior.Editable                     = true;

            this.gridView.OptionsSelection.EnableAppearanceFocusedCell = false;

            this.gridView.OptionsSelection.InvertSelection             = false;

            this.gridView.OptionsHint.ShowCellHints                    = false;

            this.gridView.OptionsClipboard.CopyColumnHeaders           = DefaultBoolean.False;

 

            #endregion

 

            #region 성명 컬럼을 설정한다.

 

            GridColumn nameColumn = new GridColumn();

 

            nameColumn.Name                    = "nameColumn";

            nameColumn.Caption                 = "Name";

            nameColumn.FieldName               = "Name";

            nameColumn.Width                   = 100;

            nameColumn.OptionsColumn.AllowEdit = false;

            nameColumn.Visible                 = true;

            nameColumn.VisibleIndex            = 0;

 

            this.gridView.Columns.Add(nameColumn);

 

            #endregion

            #region 저장소 항목 커스텀 토큰 에디터를 설정한다.

 

            RepositoryItemCustomTokenEdit repositoryItemCustomTokenEdit = new RepositoryItemCustomTokenEdit();

 

            repositoryItemCustomTokenEdit.Name              = "repositoryItemMyTokenEdit";

            repositoryItemCustomTokenEdit.AutoHeightMode    = TokenEditAutoHeightMode.RestrictedExpand;

            repositoryItemCustomTokenEdit.EditMode          = TokenEditMode.Manual;

            repositoryItemCustomTokenEdit.EditValueType     = TokenEditValueType.List;

            repositoryItemCustomTokenEdit.MaxExpandLines    = 1;

            repositoryItemCustomTokenEdit.TokenPopulateMode = TokenEditTokenPopupateMode.DisableAutoPopulate;

 

            repositoryItemCustomTokenEdit.Separators.AddRange(new string[] { "," });

 

            foreach(KeyValuePair<int, string> keyValuePair in TokenRegistry.GetTokenDictionary())

            {

                repositoryItemCustomTokenEdit.Tokens.AddToken(keyValuePair.Value, new ObjectWrapper(keyValuePair.Key));

            }

 

            this.gridControl.RepositoryItems.Add(repositoryItemCustomTokenEdit);

 

            #endregion

            #region 토큰 컬럼을 설정한다.

 

            GridColumn tokenColumn = new GridColumn();

 

            tokenColumn.Name         = "tokenColumn";

            tokenColumn.Caption      = "Token";

            tokenColumn.FieldName    = "(none)";

            tokenColumn.Width        = 300;

            tokenColumn.UnboundType  = DevExpress.Data.UnboundColumnType.Object;

            tokenColumn.Visible      = true;

            tokenColumn.VisibleIndex = 1;

            tokenColumn.ColumnEdit   = repositoryItemCustomTokenEdit;

 

            this.gridView.Columns.Add(tokenColumn);

 

            #endregion

            #region 이벤트를 설정한다.

 

            this.gridView.CustomUnboundColumnData              += gridView_CustomUnboundColumnData;

            repositoryItemCustomTokenEdit.ValidateToken        += repositoryItemCustomTokenEdit_ValidateToken;

            repositoryItemCustomTokenEdit.SelectedItemsChanged += repositoryItemCustomTokenEdit_SelectedItemsChanged;

 

            #endregion

 

            this.gridControl.DataSource = GetDataSource();

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Private

        //////////////////////////////////////////////////////////////////////////////// Event

 

        #region 그리드 뷰 커스텀 언바운드 컬럼 데이터 처리하기 - gridView_CustomUnboundColumnData(sender, e)

 

        /// <summary>

        /// 그리드 뷰 커스텀 언바운드 컬럼 데이터 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void gridView_CustomUnboundColumnData(object sender, CustomColumnDataEventArgs e)

        {

            Employee employee = e.Row as Employee;

 

            if(employee == null)

            {

                return;

            }

 

            if(e.IsGetData)

            {

                BindingList<ObjectWrapper> bindingList = new BindingList<ObjectWrapper>();

 

                foreach(string token in employee.TokenList)

                {

                    int id = TokenRegistry.GetID(token);

 

                    bindingList.Add(new ObjectWrapper(id));

                }

 

                e.Value = bindingList;

            }

        }

 

        #endregion

        #region 저장소 항목 커스텀 토큰 에디터 선택 인덱스 변경시 처리하기 - repositoryItemCustomTokenEdit_SelectedItemsChanged(sender, e)

 

        /// <summary>

        /// 저장소 항목 커스텀 토큰 에디터 선택 인덱스 변경시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void repositoryItemCustomTokenEdit_SelectedItemsChanged(object sender, ListChangedEventArgs e)

        {

            if(this.update)

            {

                return;

            }

 

            TokenEdit tokenEdit = sender as TokenEdit;

 

            if(tokenEdit == null)

            {

                return;

            }

 

            Employee employee = this.gridView.GetFocusedRow() as Employee;

 

            UpdateToken(tokenEdit, employee);

        }

 

        #endregion

        #region 저장소 항목 커스텀 토큰 에디터 토큰 검증하기 - repositoryItemCustomTokenEdit_ValidateToken(sender, e)

 

        /// <summary>

        /// 저장소 항목 커스텀 토큰 에디터 토큰 검증하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void repositoryItemCustomTokenEdit_ValidateToken(object sender, TokenEditValidateTokenEventArgs e)

        {

            int id;

 

            if(int.TryParse(e.Description, out id))

            {

                string token = TokenRegistry.GetToken(id);

 

                e.Description = token;

                e.Value       = new ObjectWrapper(id);

                e.IsValid     = true;

            }

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////// Function

 

        #region 데이터 소스 구하기 - GetDataSource()

 

        /// <summary>

        /// 데이터 소스 구하기

        /// </summary>

        /// <returns>데이터 소스</returns>

        private BindingList<Employee> GetDataSource()

        {

            BindingList<Employee> list = new BindingList<Employee>();

 

            list.Add(new Employee("John"));

            list.Add(new Employee("Carl"));

            list.Add(new Employee("Mike"));

            list.Add(new Employee("Kate"));

 

            return list;

        }

 

        #endregion

        #region 토큰 업데이트하기 - UpdateToken(tokenEdit, employee)

 

        /// <summary>

        /// 토큰 업데이트하기

        /// </summary>

        /// <param name="tokenEdit">토큰 에디터</param>

        /// <param name="employee">직원</param>

        private void UpdateToken(TokenEdit tokenEdit, Employee employee)

        {

            if(this.update)

            {

                return;

            }

 

            this.update = true;

 

            try

            {

                employee.TokenList.Clear();

 

                foreach(ObjectWrapper objectWrapper in (IList)tokenEdit.EditValue)

                {

                    string token = TokenRegistry.GetToken(objectWrapper.Source);

 

                    employee.TokenList.Add(token);

                }

 

                this.gridView.UpdateCurrentRow();

            }

            finally

            {

                this.update = false;

            }

        }

 

        #endregion

    }

}

 

 

Program.cs

 

 

using System;

using System.Windows.Forms;

 

namespace TestProject

{

    /// <summary>

    /// 프로그램

    /// </summary>

    static class Program

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region 프로그램 시작하기 - Main()

 

        /// <summary>

        /// 프로그램 시작하기

        /// </summary>

        [STAThread]

        private static void Main()

        {

            Application.EnableVisualStyles();

            Application.SetCompatibleTextRenderingDefault(false);

            Application.Run(new MainForm());

        }

 

        #endregion

    }

}

 

------------------------------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker
TAG

댓글을 달아 주세요