NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    C# C# .NET 매크로 프로그램 만들기. (최근 문서 콘트롤 만들기)

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 잠시 쉬어가는 코너로 Krypton 콘트롤의 최근 문서(Recent Documents)를 저장하고, 불러오는 방법에 대해서 알아볼께요. 그동안 매크로 제작 클라이언트의 기능을 최소한으로만 유지하고, 액션을 제작하는데 시간을 할애하고 있었습니다. 어느정도 기본 기능이 만들어지다보니 테스트를 위해 열고 닫기를 반복하는 상황이 점점 많아지고 있습니다. 파일 메뉴를 클릭하고, 스크립트 열기에서 파일을 찾아서 열기 버튼까지 많은 단계를 거쳐야 해서 상단히 귀찮더라고요. 그래서, 한번 열었던 스크립트를 최근 문서에 기록하고 열 수 있도록 했습니다.

     

    최근 문서 관련 내용은 엔지엠 6에도 있는데요. 아래와 같이 한번 열었던 스크립트를 클라이언트에 표시하는 기능입니다. 파일 메뉴를 클릭하면 오른쪽에 최근 문서가 표시됩니다.

    BztwICZ.jpeg

     

     

    최근 문서에 등록되어 있는 항목을 클릭하면 해당 스크립트가 열립니다.

    4oIeusw.jpeg

     

     

    최근 문서는 크립톤 컨트롤에서 아래와 같이 KryptonRibbonRecentDocs 안에 KryptonRibbonRecentDoc이 추가되는 방식입니다. 그리고, 이력을 별도로 관리하기 위한 모델이 하나 필요한데요. 모델은 아래와 같은 구조를 가지고 있습니다. 이 구조는 KryptonRibbonRecentDoc의 속성을 채워주는 항목들입니다.

    namespace Ai.Model.Client
    {
        [Serializable]
        public class RecentModel
        {
            public string? Name { get; set; }
    
            public DateTime OpenDate { get; set; }
    
            public string? FileName { get; set; }
        }
    }

     

    이제 스크립트를 열 때 KryptonRibbonRecentDoc을 만들고, KryptonRibbonRecentDocs 컬렉션에 추가해야 합니다. MainView에 Recent 관련 도우미 클래스를 하나 만들었습니다. Recent는 상시적으로 사용되는건 아니라서 static으로 만들 필요는 없습니다. 아무튼, 매인에서 해당 함수를 호출한 후 리본 메뉴의 최근 문서를 채워줍니다.

            private void MainView_Load(object sender, EventArgs e)
            {
                this.Text = ((Ai.Model.Client.OptionModel)this.Option).Title;
    
                new Ai.Common.Client.Control.Recent(this).RecentLoad(Ai.Common.Environment.RecentFullName);

     

    클라이언트가 종료될 때 최근 문서 내용을 파일로 저장해줍니다. 그래야 다음에 다시 열었을 때 상태가 유지되니까요.

            private void MainView_FormClosing(object sender, FormClosingEventArgs e)
            {
                new Ai.Common.Client.Control.Recent(this).RecentSave(Ai.Common.Environment.RecentFullName);
            }

     

    최근 문서 목록을 저장하고 있는 파일을 인자로 넘겨주면 해당 파일이 있는지 검사합니다. 파일이 없으면 아무런 동작도 하지 않습니다. Ribbon 메뉴는 에디터에만 있기 때문에 클라이언트를 에디터로 형변환하고, 모델을 바인딩합니다. 아직 플레이어가 없지만, 나중에 만들어지면 이 내용도 약간 수정되어야 합니다.

            public void RecentLoad(string fileName)
            {
                if (!System.IO.File.Exists(fileName))
                    return;
    
                if (new FileInfo(fileName).Length == 0)
                    return;
    
                var ribbon = ((Ai.Interface.IEditor)_client).Ribbon;
                var recents = ModelHelper.Load<List<RecentModel>>(fileName);
    
                foreach (var recent in recents.Take(9))
                {
                    ribbon.RibbonAppButton.AppButtonRecentDocs.Add(new KryptonRibbonRecentDoc()
                    {
                        Text = recent.Name,
                        ExtraText = recent.OpenDate.ToString(),
                        Tag = recent.FileName
                    });
    
                    ribbon.RibbonAppButton.AppButtonRecentDocs.Last().Click += Recent_Click;
                }
            }

     

    rectnts.Take(9)는 최근 문서를 몇개 가져올지 선택합니다. 이번에는 최근 문서를 저장하는 코드입니다.

            public void RecentSave(string fileName)
            {
                var ribbon = ((Ai.Interface.IEditor)_client).Ribbon;
                List<Model.Client.RecentModel> models = new List<Model.Client.RecentModel>();
                foreach (var recent in ribbon.RibbonAppButton.AppButtonRecentDocs)
                {
                    DateTime dt = DateTime.Now;
    
                    if (DateTime.TryParse(recent.ExtraText, out dt))
                        dt = DateTime.Parse(recent.ExtraText);
    
                    models.Add(new Model.Client.RecentModel()
                    {
                        Name = recent.Text,
                        OpenDate = dt,
                        FileName = recent.Tag?.ToString()
                    });
                }
                ModelHelper.Save(models, fileName);
            }

     

    마지막으로 최근 문서 항목을 클릭하면 이벤트가 발생하고, 해당 스크립트를 열어야 합니다. 이벤트 핸들러는 아래와 같이 구현되어 있습니다.

            private void Recent_Click(object? sender, EventArgs e)
            {
                Ai.Interface.IEditor editor = (Ai.Interface.IEditor)_client;
                KryptonRibbonRecentDoc? recent = sender as KryptonRibbonRecentDoc;
    
                if (recent == null || recent.Tag == null || !System.IO.File.Exists(recent.Tag.ToString()))
                {
                    editor.Ribbon.RibbonAppButton.AppButtonRecentDocs.Remove(recent);
                    MessageBox.Show(_client as Form, $"{new FileNotFoundException().Message}{System.Environment.NewLine}{recent.Tag.ToString()}", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
    
                var _dockHelper = new DockHelper(_client);
    
                var op = ((Ai.Interface.IEditor)_client).DockingManager.Pages.Where(w => w.Text.Equals(recent.Text)).FirstOrDefault();
                if (op != null)
                {
                    _dockHelper.ActiveView(op);
                    return;
                }
    
                var nodes = new Ai.Common.File(recent.Tag.ToString()).Deserialize<TreeNode[]>();
    
                var page = new Model.Client.DockModel()
                {
                    Name = recent.Text,
                    Text = recent.Text,
                    TextTitle = recent.Text,
                    Description = recent.Tag.ToString(),
                    Control = new Ai.Common.Client.View.Script(_client, nodes) { _isNew = false }
                };
    
                _dockHelper.AttachViews(editor.DockingManager, new Model.Client.DockModel[]
                {
                    page
                }, true);
            }

     

    여러가지 도우미 클래스들의 도움을 받아서 최근 문서를 파싱하고, 스크립트로 변환하도록 되어 있습니다. 플레이어나 디자이너를 만들때 쯤이면, 이 클래스도 리팩토링 작업이 필요할거 같습니다. 이렇게 만들면, 매인뷰에서 스크립트를 열 때 최근 문서가 추가되고, 프로그램을 종료할 때 추가된 최근 문서들의 내용을 파일로 기록합니다. 다음에 다시 실행할 때 Load 이벤트에서 파일을 읽어오기 때문에 상태를 유지할 수 있습니다.

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.