다수의 usercontrol 사용 시 폼 이동이 느려지는 문제

안녕하세요

회원정보 리스트를 만드는데 디자인을 좀 가미해서 만들고 싶어서
각각의 회원정보는 usercontrol을 통해 만들고 usercontrol은 db에서 가져온 정보로 구성한 다음
flowLayoutPanel에 올려서 리스트처럼 볼 수 있게 구성을 해봤습니다.

여기까지 보이는데는 문제가 없지만, 폼의 borderStyle을 None으로 변경 후 상단에 panel을 배치해서
mouse up, mouse down, mouse move 이벤트를 아래처럼 추가를 해주었습니다.

        bool TagMove;
        int MValX, MValY;
        private void titlePanel_MouseDown(object sender, MouseEventArgs e)
        {
            TagMove = true;
            MValX = e.X;
            MValY = e.Y;
        }

        private void titlePanel_MouseMove(object sender, MouseEventArgs e)
        {
            if (TagMove)
            {
                this.SetDesktopLocation(MousePosition.X - MValX, MousePosition.Y - MValY);
            }
        }

        private void titlePanel_MouseUp(object sender, MouseEventArgs e)
        {
            TagMove = false;
        }

그런데 이후에 폼을 마우스 드래그로 움직여보면 마우스 움직임을 너무 늦게 따라가는게 보이는데
이곳저곳 검색해보니 control 수가 많아져서 그렇다고 하는 것 같더라구요… usercontrol은 약 150개정도 생성된 상태입니다.

stackoverflow에서 아래의 해결책을 찾아서 적용해봤는데 처음보다는 빨라졌지만 여전히 느린게 보이는 수준입니다. 어떻게 해야할 지 몰라서 이곳까지 찾아서 질문 해봅니다 ㅠㅠ

this.ResizeBegin += (s, e) => { this.SuspendLayout(); };
this.ResizeEnd += (s, e) => { this.ResumeLayout(true); };
2개의 좋아요

컨트롤 150개면 아무래도 화면 렉이 생길 수 밖에 없지요
150개 상상이 잘 안 되는데 프로퍼티그리드 쓰거나 레이블 같은 건 WM_PAINT 핸들러에서 찍는 방법으로 컨트롤 수를 줄이는 게 좋겠네요
컨트롤 수를 50개 미만으로 줄이는 걸 권장합니다.

1개의 좋아요

개수는 늘어나면 늘어났지 줄어들지는 않을것 같습니다 ㅠ
윈폼의 borderStyle을 Fixed3D를 썼을때는 괜찮게 됐었는데 None으로 바꾸고나서 움직임이 느린게 확 티가나네요…

1개의 좋아요

borderStyle은 관련 없다고 생각합니다.
사실 50개도 많다고 보는데 줄일 수 없다면 WPF, WinUI 고려해야 될 것 같습니다.

1개의 좋아요

WPF, WinUI 는 해본적이 없는데 당장 기간이 좀 촉박한 상황이라 차후에 할수있다면 그쪽으로 해봐야겠네요…
답변감사드립니다!

1개의 좋아요

혹시 실행 가능한 샘플을공유 가능할까요?

1개의 좋아요

더블 버퍼링 활성화 해보세요

데이터를 db에서 가져와서 동적으로 usercontrol을 만들고 있고, 외부 폼은 텔레릭으로 구성한거라 샘플공유를 어떻게 해야할지 모르겠네요;;

DoubleBuffered = true;
사용해봤는데 별반차이가 없네요 허허 답변감사드립니다

환경이 윈폼이라면
150개의 Usercontrol이 생성되서 화면에 Add되는거라면.,
150개의 윈도우 핸들이 만들어 진것이고 또 그 핸들이 관리되고, Usercontrol이 복잡하다면
당연히 느릴 수 밖에 없을거 같습니다.

실제 화면에 보이는 뷰포트 사이즈를 계산한다음
눈에 보여지는 부분만 렌더링 하도록 처리하시는 것이 좋습니다.

이것이 UI가상화 입니다.
(WPF라면 그나마 윈폼보다는 좀 수월하게 구현 가능 합니다.)

3개의 좋아요
UserListItem[] items = new UserListItem[users.Count];
for (int i = 0; i < items.Length; i++)
{
    items[i] = new UserListItem();
    items[i].ImgLocation = userData["ImgLocation"];
    items[i].KorName = userData["korName"];
    items[i].EngName = userData["engName"];


    if (flowLayoutPanel1.Controls.Count < 0)
    {
        flowLayoutPanel1.Controls.Clear();
    }
    else
    {
        flowLayoutPanel1.Controls.Add(items[i]);
        //flowLayoutPanel2.Controls[i].Dock = DockStyle.Top;
        flowLayoutPanel1.Controls[i].Width = flowLayoutPanel1.Width - (flowLayoutPanel1.Controls[i].Margin.Horizontal);
    }
}
//flowLayoutPanel2.VerticalScroll.Visible = false;
flowLayoutPanel1.Parent = panel2;
flowLayoutPanel1.Location = new Point(0, 0);
flowLayoutPanel1.Width = panel2.ClientSize.Width + SystemInformation.VerticalScrollBarWidth;
flowLayoutPanel1.Height = panel2.ClientRectangle.Height;

flowLayoutPanel에 usercontrol을 추가하는 부분인데 부분적으로 렌더링하는건 어떤 키워드로 찾아봐야할까요??

제가 텔레릭을 사용해 보지는 않았지만 공유주신 소스코드를 참고해서 FormBorderStyleNone으로 하고 FlowLayoutPanel에 150개 컨트롤을 추가한 후 테스트 해보았는데 느려짐이 없는 수준이였습니다.
다른 문제이지 않을까 생각해봅니다.

하지만 항목을 1000개 정도로 늘리면 패널에 추가된 컨트롤 중 아래쪽 컨트롤들이 비정상 동작을 합니다. @aroooong 님의 글을 참고해서 보여지는 컨트롤만 추가한 후 가상화 처리를 해야 할 것 같아요.

제가 원인을 다수의 usercontrol을 사용해서 느려졌다고 생각한 이유는 방금 공유드린 코드만 주석처리하면 폼 이동에 어떤 문제도 발생하지 않아서 그렇게 생각을 했었습니다. 따로 백그라운드에서 쓰레드가 돌고있는것도아니고, 현재는 그저 ui만 구현중인 상태여서 최초에 flowLayoutPanel에 usercontrol을 배치하는것만 빼면 폼 이동에 문제가 없었거든요… 테스트해주신대로 저게 문제가 아니라면 어느부분을 체크해봐야할 지 감이 안오네요 하하… 테스트는 감사드립니다 ㅠㅠ

아래 글의 첫 번째 답변을 참고하시면 도움이 되지 않을까 생각합니다.

2개의 좋아요

코드를 봐야 알겠지만…
proxy (virtual proxy)를 이용하여 보이는 부분만 로딩해주세요.
대부분 그리드 컨트롤에도 virtual 모드라고 있어요 .
근데 150개정도로 느려지지 않을것같아요… 다른 이유일듯 합니다.

오… 감사합니다 저 글은 못찾았는데 보고 참고해서 해보겠습니다!

어느정도 느린부분은 해결이 됐는데 아직 완벽하진 않네요 ㅎㅎ 계속 찾아봐야겠습니다 감사합니다!

도움이 되실지 모르겠지만 아래 내용 참고 하세요.

1개의 좋아요