退会されてしまったようですが。。。
せっかく準備したので他の方にも役立つよう回答しておきます。
まずViewModel
ですが、WPFにおいて必須ではありません。
なくても作れます。回答では使いませんでした。
しかし使わないとWPFの魅力が8割減なので、ぜひ「wpf mvvm」等で調べてみてください。
その際に記事中で使用されているReactiveProperty
も出てくると思います。
何度も使うということですとMainWindow
内に用意して、ビジー中だけすべてのコントロールの上に覆いかぶさるような作りがいいと思います。
回転し続けるC
を描いておいて、必要に応じてVisibility
で制御します。
xml:MainWindow.xaml
1<Window
2 x:Class="Questions256032.MainWindow"
3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5 Width="800"
6 Height="450">
7 <Grid>
8
9 <!-- ここに通常のUI要素 -->
10 <Grid>
11 <Grid.RowDefinitions>
12 <RowDefinition Height="Auto" />
13 <RowDefinition Height="Auto" />
14 <RowDefinition />
15 </Grid.RowDefinitions>
16 <TextBlock
17 x:Name="textBlock"
18 Margin="10"
19 Text="ほにゃらら" />
20 <TextBox
21 Grid.Row="1"
22 Margin="10"
23 Text="なんだかんだ" />
24 <Button
25 Grid.Row="2"
26 HorizontalAlignment="Center"
27 VerticalAlignment="Center"
28 Click="Button_Click"
29 Content="なんか重い処理を始めます" />
30
31 </Grid>
32
33
34 <!-- これが上にかぶさるビジーインジケーター -->
35 <Grid x:Name="busy" Visibility="Hidden">
36
37 <!-- ビジー中はボタン等をいじれないように半透明のGridを表示 -->
38 <Grid Background="Black" Opacity="0.2" />
39 <!--<Image Source="hoge.png" />-->
40
41 <!-- Cの字 -->
42 <!-- 大きさを変える場合以下の50を全部変える -->
43 <Path
44 HorizontalAlignment="Center"
45 VerticalAlignment="Center"
46 Stroke="Blue"
47 StrokeThickness="10">
48 <Path.Data>
49 <PathGeometry>
50 <PathGeometry.Figures>
51 <PathFigure StartPoint="50,0">
52 <ArcSegment
53 IsLargeArc="True"
54 Point="0,50"
55 Size="50,50"
56 SweepDirection="Clockwise" />
57 </PathFigure>
58 </PathGeometry.Figures>
59 </PathGeometry>
60 </Path.Data>
61 <Path.RenderTransform>
62 <RotateTransform CenterX="50" CenterY="50" />
63 </Path.RenderTransform>
64 <Path.Triggers>
65 <EventTrigger RoutedEvent="Loaded">
66 <BeginStoryboard>
67 <Storyboard>
68 <!-- 回り続けるアニメーション Duration でスピードの変更 -->
69 <DoubleAnimation
70 RepeatBehavior="Forever"
71 Storyboard.TargetProperty="RenderTransform.(RotateTransform.Angle)"
72 To="360"
73 Duration="0:0:1.5" />
74 </Storyboard>
75 </BeginStoryboard>
76 </EventTrigger>
77 </Path.Triggers>
78 </Path>
79 </Grid>
80 </Grid>
81</Window>
cs:MainWindow.xaml.cs
1using System.Threading;
2using System.Threading.Tasks;
3using System.Windows;
4
5namespace Questions256032
6{
7 public partial class MainWindow : Window
8 {
9 public MainWindow()
10 {
11 InitializeComponent();
12 }
13
14 private async void Button_Click(object sender, RoutedEventArgs e)
15 {
16 textBlock.Text = "重たい処理を始めるよ";
17 busy.Visibility = Visibility.Visible;
18
19 await Task.Run(() => HeavyWork());
20
21 busy.Visibility = Visibility.Hidden;
22 textBlock.Text = "終わったよ";
23 }
24
25 // なんか重たい処理をする
26 private void HeavyWork()
27 {
28 Thread.Sleep(5000);
29
30 // NG ここでは普通にはUI要素に触れない
31 //textBlock.Text = "あとちょっと";
32
33 // OK
34 Dispatcher.Invoke(() => textBlock.Text = "あとちょっと");
35
36 Thread.Sleep(3000);
37 }
38 }
39}