Text 몇 초 후에 사라지게

안녕하세요.

if를 탔을 때 label에 에러 내용을 표시하게 했습니다.

에러 내용은 3초 정도만 표시되고 그 뒤로는 사라지게 하고 싶은데

도움 주시면 감사하겠습니다…!

if (sum!= 100)
{
    ErrorMsg.Text = "[Error]\n\n합은 100 입니다.";               
    return false; 
}            
else
{
    ErrorMsg.Text = "";
}
2개의 좋아요

프레임워크를 뭘 쓰시는 지를 명확히 해주셔야 할 거 같습니다.

예를 들면 ConsoleApp 에는 Label 이라는 컨트롤이 없습니다.

Windows Forms라고 가정하고 말하겠습니다.

System.Windows.Forms.Timer 클래스의 Tick 이벤트를 알아보시면 도움이 되실 것 같습니다.

3개의 좋아요

async, await를 사용해보세요~

public async bool Sample()
{
    if (sum!= 100)
    {
        ErrorMsg.Text = “[Error]\n\n합은 100 입니다.”;
        await Task.Delay(3000);
        ErrorMsg.Text = string.Empty;
        return false;
    }
    else
    {
        ErrorMsg.Text = “”;
    }
}
6개의 좋아요

a. Windows Forms의 경우 @Vincent 님의 말씀처럼 타이머 컴포넌트를 추가해서 일정 시간이 되면 컨트롤을 감추는 동작을 Tick 이벤트 핸들러를 추가하여 구현하시면 되겠습니다. WPF의 경우 DispatcherTImer를 이용하시거나 @hiron88 님의 코드를 참고하시면 될 것 같습니다.

b. @hiron88 님의 코드에서 Sample 메서드의 반환 시그니처는 실제로는 컴파일되지 않을 것 같습니다. async void Sample() 이거나 async Task<bool> Sample()이 컴파일 가능한 코드가 될 것 같습니다.

c. @hiron88 님의 구현도 가능은 하지만 주의하실 것이 있습니다. Windows Forms, WPF 모두 UI 스레드는 1개이고, async/await을 사용해서 UI 스레드와 병렬로 분리된 스레드를 실행할 때는 Windows Forms이든 WPF이든 UI 요소를 UI 스레드가 아닌 스레드가 제어할 경우 스레드 데드락 문제 예방을 위해서 프레임워크 수준에서 Exception을 띄우거나, 혹은 이런 처리가 되어있지 않은 코너 케이스를 만날 경우 UI가 얼어버리는 문제가 발생할 수 있습니다.

UI 프레임워크에서 UI 스레드가 대신 작업을 받아서 처리할 수 있도록 해주는 수단 (예: Windows Forms의 경우 Control.Invoke, WPF의 경우 Application.Current.Dispatcher.Invoke API)을 사용해야 안전하게 구현이 가능합니다.

5개의 좋아요

그리고 UI 프로그래밍 관련 질문은 C# 게시판이 아닌 윈도우 데스크톱 Q&A 게시판에 향후에는 올려주시면 감사하겠습니다. 카테고리는 변경해드렸습니다.

4개의 좋아요

사실 주신 질문은 생각보다 쉽지 않은 작업입니다.

UI 쓰레드를 다른 쓰레드에서 건들여야 하는 작업이기 때문입니다.

아래는 제가 비슷한 질문에 답글을 달았던 내용인데 WPF를 사용하신다면
아래의 코드를 이용해서 작업해보시겠어요?

//  여기서 최초 UI 변경

int millisecondsDelay = 3000; // 3초

Task.Run(async() =>
{
    await Task.Delay(millisecondsDelay); // 3초 대기

    // it only works in WPF
    Application.Current.Dispatcher.Invoke(() =>
    {
        // Do something on the UI thread.
        // UI 쓰레드에서 사라지는 작업 위임
    });
});
3개의 좋아요

사실 위의 코드는 아래처럼 간단히 가능합니다.

//  여기서 최초 UI 변경

int millisecondsDelay = 3000; // 3초

await Task.Delay(millisecondsDelay); // 3초 대기

// Do something on the UI thread.
// UI 쓰레드에서 사라지는 작업 위임

SynchronizationContext에 의해 await 이후의 코드는 다시 UI 스레드로 복귀되며 정상 동작합니다.

다만 생성자 등에서는 async를 쓸 수 없으므로 @마수리 님과 같은 코드를 쓰기도 합니다.

6개의 좋아요

C++이긴 한데 WinUI 3 DispatcherTimer OnTick Handler에서 Text 바꿔도 문제 없었습니다.
오류 나면 DispatcherQueue TryEnqueue로 할 생각이었는데 필요치 않더군요

2개의 좋아요

안녕하세요 이렇게 제 코드에 피드백을 주셔서 감사합니다.

await 이후에 UI쓰레드로 복귀하니 저렇게 사용할 수도 있겠네요!

하나 배우고 갑니다 감사합니다!

1개의 좋아요

많은 분들이 스레드를 사용해 비동기 async / await 처리로
답변을 달아 주셨는데

Storyboard를 사용해서 토스트 메세지 처럼 n초 후 서서히 사라지도록 할 수 있습니다.
Storyboard 사용으로 별도 스레드 사용 없이 UI스레드 블락 없이
매끄럽게 처리가 가능합니다.

[xaml]

<Border x:Name="xToastBorder"
                Grid.Row="1"
                Background="#FF7E7E7E"
                VerticalAlignment="Bottom"
                HorizontalAlignment="Center"
                CornerRadius="5"
                Visibility="Collapsed"
                Margin="0, 0, 0, 30">
            <TextBlock x:Name="xToastMessage"
                       FontSize="17"
                       TextAlignment="Center"
                       VerticalAlignment="Center"
                       Foreground="#FFFFFFFF"
                       Margin="10, 5, 10, 5"
                       Style="{StaticResource xNanumSquareFont}" />
</Border>

위 Border에 Storyboard 적용 - duration 설정을 사용자 측에서 설정할 수 있도록
코드비하인드로 Storyboard 작성

[cs]

public void ShowToastMessage(string message, int duration)
{
            this.xToastMessage.Text = message;
            this.xToastBorder.Visibility = Visibility.Visible;

            Storyboard toastStoryBoard = new Storyboard();
            toastStoryBoard.Completed += (sender, _) =>
            {
                this.xToastBorder.Visibility = Visibility.Collapsed;
                toastStoryBoard = null;
            };

            Storyboard.SetTargetProperty(toastStoryBoard, new
                PropertyPath("(Border.Opacity)"));

            DoubleAnimation fadeInToast = new DoubleAnimation(0, 1, TimeSpan.FromSeconds(1));
            DoubleAnimation fadeOutToast = new DoubleAnimation(1, 0, TimeSpan.FromSeconds(1));
            fadeOutToast.BeginTime = TimeSpan.FromMilliseconds(duration);

            Storyboard.SetTargetName(fadeInToast, this.xToastBorder.Name);
            Storyboard.SetTargetName(fadeOutToast, this.xToastBorder.Name);

            toastStoryBoard.Children.Add(fadeInToast);
            toastStoryBoard.Children.Add(fadeOutToast);

            toastStoryBoard.Begin(this);
}

그리고 이렇게 사용할 수 있어요!

// 3초 동안 텍스트 표시 후 사라짐
this.ShowToastMessage("잠깐동안 표시하고 싶은 텍스트", 3000); 

위 ShowToastMessage() 메서드를 어디서든 공통으로 사용 가능 하도록 static으로 처리하고
xaml 부분을 공통으로 사용할 수 있도록 잘 처리하면 공용으로 사용할 수 있습니다.


그리고 결과는 이렇게 나와요!
show

9개의 좋아요

굿입니다! ^^

1개의 좋아요