반응형
나는조이
쑥쑥 크는 조이
나는조이
  • 분류 전체보기 (66)
    • 나누며 성장하기 (14)
      • Raktivist's Diary (4)
      • 성장 코칭 Growth Coaching (2)
      • 일상 · 생각 (8)
    • 읽고 성장하기 (1)
    • 공부하며 성장하기 (51)
      • 인공지능 AI (34)
      • AWS (1)
      • 파이썬 Python (6)
      • C# · WPF (1)
      • Fixing Errors (6)
      • 인사이트 리뷰 Insight Review (2)
      • AI-struction (1)

인기 글

최근 댓글

공지사항

  • def introduce(self):
전체 방문자
오늘
어제
ⓒ2022 @nanunzoey.All rights reserved.
hELLO · Designed By 정상우.
나는조이

쑥쑥 크는 조이

새 창에서 진행률 progress bar 표시하기
공부하며 성장하기/C# · WPF

새 창에서 진행률 progress bar 표시하기

2024. 4. 4. 09:39

 

background thread에서 수행하고 있는 task에 대해 새 창에서 진행률을 보여주려면 UI thread로 해당 부분을 넘겨줘야 한다.
그러려면 BackgroundWorker와 Dispatcher가 필요하다.

https://spinify.com/wp-content/uploads/2017/03/Work-In-Progress-1-1.jpg

 

아래 코드는 기본적인 로직만 담고 있다. 필요한 경우에 가져다 쓰면 된다.

// MainWindow.xaml
<Window x:Class="TestProgress.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestProgress"
        mc:Ignorable="d"
        Title="테스트" Height="450" Width="800">
	<Grid>
         <Button Content="작업 시작" Click="StartButton_Click"/>
	</Grid>
</Window>
// TestProgress.xaml.cs (Main Window)
namespace TestProgress
{
    public partial class MainWindow : Window
    {
        private BackgroundWorker Worker;
        private ProgressWindow ProgressBarWindow;

        public MainWindow()
        {
            InitializeComponent();
        }

    private void StartButton_Click()
    {
        Worker = new()
        {
            WorkerReportsProgress = true,
            WorkerSupportsCancellation = true  // optional
        };
        Worker.DoWork += Worker_RunTask;
        Worker.ProgressChanged += Worker_ProgressChanged;
        Worker.RunWorkerCompleted += Worker_RunCompleted;  // optional

        Dispatcher.Invoke(() =>
        {
            ProgressBarWindow = new();
            ProgressBarWindow.Show();
        });
        Worker.RunWorkerAsync();
    }
    
	private void Worker_RunTask(object sender, DoWorkEventArgs e)
    {
        int processedCount = 0;
        foreach (string file in selectedFiles)  // 어떤 형태든 반복문
        {
            // 취소 버튼 클릭 시 중단
            if (cropWorker.CancellationPending)
            {
                e.Cancel = true;
                return;
            }
            
            // 원하는 작업 수행

			// 진행률 업데이트
            processedCount++;
            int progress = (int)((double)processedCount / selectedFiles.Length * 100);
            (sender as BackgroundWorker).ReportProgress(progress);
        }
    }

	// 작업 진행률 업데이트
    private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        ProgressBarWindow.UpdateProgress(e.ProgressPercentage);
    }

	// 작업 완료 시 수행할 것
    private void Worker_RunCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        Dispatcher.Invoke(() => {
            ProgressBarWindow.Close();
        });
        MessageBox.Show("작업이 완료되었습니다.");
    }
    
    public void CancelTask()
    {
        Worker.CancelAsync();
    }
}
// ProgressWindow.xaml
<Window x:Class="TestProgress.ProgressWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestProgress"
        mc:Ignorable="d"
        Title="작업 중..." Height="150" Width="450">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Center">
            <ProgressBar x:Name="progressBar" Minimum="0" Maximum="100" Height="20" Width="410" Margin="20 25" VerticalAlignment="Top" HorizontalAlignment="Center" Visibility="Visible" />
            <TextBlock Name="progressBarText" Text="{Binding ElementName=progressBar, Path=Value, StringFormat={}{0:0} %}" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="-232"/>
        </StackPanel>
        <Button Grid.Row="0" Grid.Column="0" x:Name="cancelButton" Content="작업 취소" Margin="20 12" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="80" Height="35" Click="CancelButton_Click" />
    </Grid>
</Window>
// ProgressWindow.xaml.cs
using System.ComponentModel;
using System.Windows;

namespace AutomatedTrainingSystem
{
    public partial class ProgressWindow : Window
    {
        public ProgressWindow()
        {
            InitializeComponent();
        }

        public void UpdateProgress(int value)
        {
            Dispatcher.Invoke(() => progressBar.Value = value);
        }
        
        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            (Application.Current.MainWindow as MainWindow)?.CancelTask();
        }
    }
}

 

반응형
저작자표시 비영리 변경금지
    나는조이
    나는조이
    매일 쑥쑥 크는 성장기를 담습니다.

    티스토리툴바