홈>
Winform itch에 버튼, 2 개의 레이블 및 이미지가있는 패널이 있습니다. 이제 진행률 표시 줄로 패널 배경의 색상을 아래쪽에서 위쪽으로 점차 변경하고 싶습니다. 두 번째 패널이있는 구성 요소가있는 패널을 사용하여 첫 번째 패널 위에 있지만 구성 요소 뒤에 시도한 다음 점차 두 번째 패널의 높이를 확장했습니다. 그러나 구성 요소의 배경색은 첫 번째 패널의 색을 상기시킵니다. 구성 요소의 배경색을 투명하게 설정하려고했습니다.
이 효과를 달성하기위한 제안이있는 사람이 있습니까? 패널과 함께있을 필요는 없습니다. 구성 요소가 해당 영역의 맨 위에 있고 배경색이 변하기 만하면됩니다.
미리 감사합니다
- 답변 # 1
관련 질문
- c# : 다른 스레드를 기다리는 동안 Application.DoEvents
- c# : 양식이 로드되었는지 확인
- c# : 다른 UserControl에서 사용자 컨트롤을 어떻게 변경할 수 있습니까?
- c# : DataGridviewColumnCollection을 ComboBox.DataSource에 성공적으로 바인딩하고 Display/ValueMember를 지정할 수 없는 이유는 무엇입니까?
- c# : DesignerSerializationVisibilityAttribute 없이 사용자 정의 컨트롤의 명명 직렬화
- c# : 다른 응용 프로그램에 포함된 글꼴 사용
- c# : HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node를 보려면 관리자 권한으로 Regedit를 엽니다.
- C# WinForms -Designer에서 설정한 레이블 값을 표시하지 않는 폼의 인스턴스
- c# : MessageBox.Show가 맨 위에 표시되도록 합니다.
- c# : Entity Framework 6 및 WinForm DataGrid의 문제
Windows Forms 응용 프로그램을 사용하면 원하는 효과를 얻을 수 있습니다. 거기에 당신을 데려 갈 많은 옵션이 있지만, 나는
<시간> 와이즈 비즈 옵션Paint
를 다룰 것입니다 사용자에게 사각형을 페인트하여 진행 상황을 사용자에게 표시 할 수있는 이벤트 옵션. 이 경로를 효과적으로 보여주는 두 가지 방법이 있습니다. 그 중 하나는Timer
를 사용한 단순한 접근 방식입니다 다른 하나는보다 심층적 인 접근 방법이지만 백그라운드 스레드에서 진행률을 표시하는 데 더 적합합니다.Timer
사용 최소한의 코드로이 효과를 재현 할 수 있습니다. 당신은 단순히Timer
가 필요합니다 ,Panel
그리고Timer
진행 상황을 추적합니다. Wyzwyz에서 우리는float
에 타이머를 시작 진행률을 높이고 패널을 무효화하고FormLoad
에서 우리는 우리의 커스텀 진보를 그린다 :알다시피,이 방법의 코드는 매우 간단하고 쉽게 설명 할 수 있습니다.
<시간> 이벤트 옵션백그라운드 스레드에 물건을로드 할 때
PanelPaint
와 같은 GUI 요소를 업데이트 할 때 상황이 조금 더 복잡해질 수 있습니다 . 이 경우 나는private float progress = 0f; private void Form1_Load(object sender, EventArgs e) => timer1.Start(); private void timer1_Tick(object sender, EventArgs e) { progress += 0.01f; if (progress >= 1.0f) progress = 0f; panel1.Invalidate(); } private void panel1_Paint(object sender, PaintEventArgs e) { e.Graphics.FillRectangle(Brushes.Green, new Rectangle(0, 0, panel1.Width, (int)(panel1.Height * progress))); }
를 사용하는 것을 선호합니다Panel
를 발생시키지 않고 GUI 요소를 업데이트하는 양식에서 이벤트를 발생시키는 방법 에스. 그러나이 특정 예제에서는 상황이 비교적 간단하고 위와 같은 방식으로 작동하지만 더 많은 코드가 사용됩니다. 우리SynchronizationContext
가 있다고 모든 백그라운드 로딩을 처리하며 모두 별도의 스레드에서 발생합니다. 이 경우 양식에 가입 한 커스텀 이벤트와CrossThreadException
가 있습니다. 폼이 GUI를 업데이트 할 수 있도록 이벤트를 발생시킵니다.이제 로딩 클래스가 빌드되고 객체와 그 재미있는 재즈가 모두 생성되었으므로 타이머와 동일한 작업을 수행하기 위해 폼 코드에 추가 할 수 있습니다. 이 방법으로 우리는
<시간> 바닥에서 사각형 채우기SyncrhonizationContext
를 구독합니다 이벤트와 동일한 프로세스를 따릅니다.아래에서 직사각형을 채우려면 위치와 높이를 동시에 조정해야합니다.
오른쪽에서 왼쪽으로의 동일한 개념과 왼쪽에서 오른쪽으로의 원래 예제를 따를 수 있습니다.
스모크 로더와 같은 연기 및 거울 모양의 외관을 얻기 위해 특정 지점에서 시작하는 기술도 있지만 필요한 경우 알아볼 수 있도록 남겨 두겠습니다.
또한 당신의
<시간> 100 %로 진행 중지int height = panel1.Height * progress; Rectangle bounds = new Rectangle(0, panel1.height - height, panel1.Width, height); e.Graphics.FillRectangle(Brushes.Green, bounds)
를 기억하십시오width = panel1.width * progress; Rectangle bounds = new Rectangle(panel1.Width - width, 0, width, panel1.Height);
이어야한다Progress
사이의 가치 그리고float
;그렇지 않으면0
로 나누어야합니다 위를 수행 할 때. 진행이1
사이에있는 경우 그리고100
그냥0
를 곱하십시오 표시 목적으로. 나는 항상1
사이에 진행을 유지하는 것이 더 쉽다는 것을 알았습니다 그리고100
계산에 많이 사용하고 한 번만 표시하기 때문에 사용합니다.의견에서 나는 당신이 내 예제에서 진행 증분을 남겼으며
0
에 의해 증가한다고 생각합니다. . 이것은 올바른 방법이 아니며 단지 예일뿐입니다.전통적으로 총 작업 수 (또는 파일의 경우 총 크기)를 파악하고 완료된 양을 해당 총 수로 나누어 진행 상황을 파악할 수 있습니다. 아래는 처리 할 객체 목록이있는 기본 예입니다.
이 특별한 경우에, 당신은0.01f
에 대한 호출을 제거합니다 Wyzwyz에서 중복 이벤트 발생을 방지하기 위해 메소드의 while 루프. <시간>사용 된 유형 중 하나라도 익숙하지 않은 경우 MSDN 설명서를 자유롭게보십시오. 아래에 가장 흔하지 않은 부분이 포함되어 있습니다. 관심있는 항목이 목록에 없으면 사과드립니다. 언제든지 댓글을 달고 추가 할 수 있습니다.
동기화 컨텍스트
나사
보내기 및 게시
또한 미래 독자들에게 발생할 수있는 질문에 대답하기 위해;내가
private List<object> ObjectsToLoad = new List<object>(); private void DoCoolStuff() { int objectsLoaded = 0; foreach (object o in ObjectsToLoad) { // Process the object. Progress = (float)++objectsLoaded / (float)ObjectsToLoad.Count;; OnObjectLoaded(); } }
를 사용한 이유OnObjectLoaded
대신 이 경우 백그라운드 스레드가 실제로 GUI가 수행 해야하는 작업에 관심이 있다고 믿지 않았기 때문에 GUI에 알려야했습니다. 와이즈 비즈 스레드가 처리를 계속하도록 지시하면서Load
스레드가loadingContext.Post
를 기다리도록 지시합니다. GUI 스레드에서. 와이즈 비즈 GUI가 백그라운드 스레드에서 전송 한 데이터를 조작 한 다음 다시 보내거나 백그라운드 스레드에서 무언가를 업데이트해야 할 때 가장 적합합니다.향후의 노력에 당신에게 행운을 빕니다!
loadingContext.Send