2Bbear's knowledge workshop

목표 :

간단하게 [작업] , [로딩바 형태] ,[로딩바 출력 위치] ,[실제 좌표 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
<UserControl x:Class="기는 알아서 해주세여"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             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;
using System.Windows.Media;
 
namespace 이건 알아서 해주세여
{
    /// <summary>
    /// </summary>
    public partial class LoadingControl : UserControl
    {
        public LoadingControl()
        {
            InitializeComponent();
            // 애니메이션 설정
            DoubleAnimation dba1 = new DoubleAnimation();  // 애니메이션 생성
            dba1.From = 0;   // start 값
            dba1.To = 360;   // end 값
            dba1.Duration = new Duration(TimeSpan.FromSeconds(1));  // 1.5초 동안 실행
            dba1.RepeatBehavior = RepeatBehavior.Forever;  // 무한 반복
 
            RotateTransform rt = new RotateTransform();
            imgLoading.RenderTransform = rt;
            rt.CenterX += imgLoading.Width / 2;
            rt.CenterY += imgLoading.Height / 2;
 
            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=여기는 알아서 해주세여"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             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.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
 
namespace 여기는 알아서 해주세여
{
    /// <summary>
    /// </summary>
    public partial class LoadingWindow : Window
    {
        Func<object> taskMethod;
        Func<objectbool> 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<objectbool> _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<objectbool> 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(
                new NH80.Config.CommonWindow.Loading.LoadingControl()
                , ()=>{
                    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위치