WPF 비동기 async 로딩바 만들기
목표 :
간단하게 [작업] , [로딩바 형태] ,[로딩바 출력 위치] ,[실제 좌표 x ,y] 이 값 만으로 간단하게 작업 을 처리하는 도중에 로딩바가 출력되는 기능을 만들려고한다.
미리보는 형태 :
-호출
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
LoadingWindow loadingWindow = new LoadingWindow(
new LoadingUserControl() ,
()=>{
int a =0;
for(int i =0;i<10;i++)
{
a+=1;
Thread.Sleep(100);
}
return a.ToString();
} ,
(object taskResult)=>{
this.Tilte=(string) taskResult;
return true;
} ,
this.Top + (this.Height /2) -100 ,
this.Left +(this.Width /2 )-100
);
loadingWindow.ShowDialog();
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
이런 식으로 (로딩바컨트롤, 작업, UI출현작업, 출현위치 y, 출현위치 x)
======
-흐름
async를 이용하여 Data를 비동기적으로 처리하고 await을 통해 데이터가 끝나는 것을 기다린다. 그 사이에 로딩바는 계속 출력되고 있는 상태인 것이다.
자동적으로 await이 끝나자마자 다시 MainWindow의 UI를 수정하게 하여 데이터가 적용되게 한다.
그 사이에 MainWindow에는 어떠한 이벤트도 발생하면 안되기 때문에 Loading을 Modal로 출력시킨다.
따라서 MainWindow는 잠기게 되고 안전하게 작업을 처리 할 수 있게된다.
-코드
LoadingControl.xaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
mc:Ignorable="d"
>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" >
<Image x:Name="imgLoading" HorizontalAlignment="Center" Height="130" VerticalAlignment="Center" Width="130" Source="Images/lodingLogo001.png"/>
<Label Content="Loading" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20" FontWeight="Bold" />
</Grid>
</UserControl>
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
LoadingControl.xaml.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
using System;
using System.Windows;
using System.Windows.Controls;
namespace 이건 알아서 해주세여
{
/// <summary>
/// </summary>
public partial class LoadingControl : UserControl
{
public LoadingControl()
{
InitializeComponent();
// 애니메이션 설정
DoubleAnimation dba1 = new DoubleAnimation(); // 애니메이션 생성
dba1.Duration = new Duration(TimeSpan.FromSeconds(1)); // 1.5초 동안 실행
dba1.RepeatBehavior = RepeatBehavior.Forever; // 무한 반복
RotateTransform rt = new RotateTransform();
imgLoading.RenderTransform = rt;
rt.BeginAnimation(RotateTransform.AngleProperty, dba1); // 변경할 속성값, 대상애니매이션
}
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
LoadingWindow.xaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<Window x:Class=여기는 알아서 해주세여"
mc:Ignorable="d"
WindowStyle="None"
AllowsTransparency="True"
ContentRendered="Window_ContentRendered"
Width="300" Height="300"
>
<Window.Background>
<SolidColorBrush Opacity="0" Color="White"/>
</Window.Background>
<ContentControl Name="LoadingImageContent">
</ContentControl>
</Window>
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
Loadingwindow.xaml.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
using System;
using System.Windows;
using System.Windows.Controls;
namespace 여기는 알아서 해주세여
{
/// <summary>
/// </summary>
public partial class LoadingWindow : Window
{
Func<object> taskMethod;
Func<object, bool> logicLambda;
/// <summary>
/// 작업을 하면서 로딩창이 뜨는 생성자
/// <param name="_loadingControl"> 어떠한 로딩화면을 출력할 것인지</param>
/// <param name="_taskMethod"> UI에 간섭하지 않고 시간이 오래걸리는 작업을 할당해야함</param>
/// <param name="_logicLambda"> _taskMethod에서 나온 결과값을 어떻게 UI로 처리 할 것인지</param>
/// <param name="_windowTop"> 해당 화면이 출력될 Y위치</param>
/// <param name="_windowLeft"> 해당 화면이 출력될 X위치</param>
public LoadingWindow(ContentControl _loadingControl,Func<object> _taskMethod, Func<object, bool> _logicLambda,double _windowTop, double _windowLeft)
{
InitializeComponent();
LoadingImageContent.Content = _loadingControl;
taskMethod = _taskMethod;
logicLambda = _logicLambda;
this.Top = _windowTop;
this.Left = _windowLeft;
}
private async void DoTask(Func<object> _taskMethod, Func<object, bool> logicLambda)
{
Task<object> task1 = Task<object>.Run(_taskMethod);
logicLambda(await task1);
Close();
}
private void Window_ContentRendered(object sender, EventArgs e)
{
DoTask(taskMethod, logicLambda);
}
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
MainWindow.xaml.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
/// <summary>
/// 로딩바가 출력되는지 테스트하는 코드, 로딩바를 테스트하고 싶다면 해당 메소드를 호출하기만 하면 됩니다.
/// </summary>
private void TestLoading()
{
Config.CommonWindow.Loading.LoadingWindow loadingWindow=new Config.CommonWindow.Loading.LoadingWindow(
, ()=>{
int a = 0;
for (int i = 0; i < 50; i++)
{
a += i;
Thread.Sleep(100);
}
return a.ToString();
}
,(object taskResult)=>{
this.Title = (string)taskResult; //task의 결과 값이 특정한 Type일때 해당 Type으로 강제 형변환 해야함
return true;
}
, this.Top + (this.Height / 2) - 100
, this.Left + (this.Width / 2) - 100
);
loadingWindow.ShowDialog();
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
-설명
Main에서는 간단하게 LoadingWindow를 생성하고 showdialog를 호출하면 끝난다.
다만 생성하는 과정에서
1 param : 어떤 로딩 화면을 출력 시킬 것인지
2 param : 어떤 작업을 실행 시킬 것인지. ui에 간섭하면 안된다. 오직 data만 다루는 작업이어야 한다. 간단하게 메소드 이름만 넣어도 충분하다. 반환형이 void 인 것은 안된다.
3 param : UI에 적용되게 UI에 간섭하는 코드를 작성한다.
4 param : 로딩바가 출력될 y 위치
5 param : 로딩바가 출력될 x위치
'Code > C#' 카테고리의 다른 글
WPF 라이프사이클 (0) | 2019.04.07 |
---|---|
WPF CheckBox 색 바꾸는 방법 (0) | 2019.04.07 |
WPF 배경이 없는 이미지 버튼 만들기(Hover 배경색 변경가능) (0) | 2019.03.28 |
WPF ToolTip 기본 컨트롤 스타일 재정의 하는 방법 (0) | 2019.03.28 |
WPF Combobox 선택 이벤트, old 값이 나올때 (0) | 2019.03.19 |