Skip to content

Commit dc075a5

Browse files
committed
Use VSM instead of IsVisible property for MAUI
1 parent 1d8041b commit dc075a5

4 files changed

Lines changed: 110 additions & 13 deletions

File tree

src/Codebreaker.MAUI/Views/Components/GameResultDisplay.xaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,28 @@
88
x:Name="this"
99
x:DataType="{x:Type vm:GamePageViewModel}">
1010
<Grid>
11+
<VisualStateManager.VisualStateGroups>
12+
<VisualStateGroup>
13+
<VisualState x:Name="Default">
14+
<VisualState.Setters>
15+
<Setter TargetName="WonPanel" Property="IsVisible" Value="False" />
16+
<Setter TargetName="LostPanel" Property="IsVisible" Value="False" />
17+
</VisualState.Setters>
18+
</VisualState>
19+
<VisualState x:Name="Won">
20+
<VisualState.Setters>
21+
<Setter TargetName="WonPanel" Property="IsVisible" Value="True" />
22+
<Setter TargetName="LostPanel" Property="IsVisible" Value="False" />
23+
</VisualState.Setters>
24+
</VisualState>
25+
<VisualState x:Name="Lost">
26+
<VisualState.Setters>
27+
<Setter TargetName="WonPanel" Property="IsVisible" Value="False" />
28+
<Setter TargetName="LostPanel" Property="IsVisible" Value="True" />
29+
</VisualState.Setters>
30+
</VisualState>
31+
</VisualStateGroup>
32+
</VisualStateManager.VisualStateGroups>
1133
<VerticalStackLayout IsVisible="{Binding GameStatus, Mode=OneWay, Converter={converter:GameStatusToIsVisibleConverter}, ConverterParameter=Won}">
1234
<Image Source="wonanimation_300_opt.gif" IsAnimationPlaying="True" MaximumHeightRequest="300" />
1335
<Label Text="Congratulations - you won the game 🎉🏆" FontSize="20" HorizontalOptions="Center" Margin="0,50,0,20" />
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,37 @@
1+
using System.ComponentModel;
2+
13
namespace Codebreaker.MAUI.Views.Components;
24

35
public partial class GameResultDisplay : ContentView
46
{
57
public GameResultDisplay()
68
{
79
InitializeComponent();
10+
Loaded += OnLoaded;
11+
GoToState("Default");
12+
}
13+
14+
public GamePageViewModel ViewModel => (GamePageViewModel)BindingContext;
15+
16+
private void OnLoaded(object? sender, EventArgs e)
17+
{
18+
ViewModel.PropertyChanged += OnViewModelPropertyChanged;
819
}
20+
21+
private void OnViewModelPropertyChanged(object? sender, PropertyChangedEventArgs args)
22+
{
23+
if (args.PropertyName != nameof(GamePageViewModel.GameStatus))
24+
return;
25+
26+
var stateName = ViewModel.GameStatus switch
27+
{
28+
GameMode.Won => "Won",
29+
GameMode.Lost => "Lost",
30+
_ => "Default"
31+
};
32+
GoToState(stateName);
33+
}
34+
35+
private void GoToState(string stateName) =>
36+
VisualStateManager.GoToState(this, stateName);
937
}

src/Codebreaker.MAUI/Views/Pages/GamePage.xaml

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,43 @@
1414
<ContentPage.Resources>
1515
<conv:GameStatusToIsVisibleConverter x:Key="GameStatusVisibleConverter" />
1616
</ContentPage.Resources>
17-
<Grid RowDefinitions="auto, auto, *" Padding="15">
17+
18+
<Grid RowDefinitions="auto, auto, *" Padding="15" x:Name="ContentWrapper">
19+
<VisualStateManager.VisualStateGroups>
20+
<VisualStateGroup>
21+
<VisualState x:Name="Start">
22+
<VisualState.Setters>
23+
<Setter TargetName="StartGameArea" Property="IsVisible" Value="True" />
24+
<Setter TargetName="PegSelectionArea" Property="IsVisible" Value="False" />
25+
<Setter TargetName="PegScrollView" Property="IsVisible" Value="False" />
26+
</VisualState.Setters>
27+
</VisualState>
28+
<VisualState x:Name="Playing">
29+
<VisualState.Setters>
30+
<Setter TargetName="StartGameArea" Property="IsVisible" Value="False" />
31+
<Setter TargetName="PegSelectionArea" Property="IsVisible" Value="True" />
32+
<Setter TargetName="PegScrollView" Property="IsVisible" Value="True" />
33+
</VisualState.Setters>
34+
</VisualState>
35+
<VisualState x:Name="Finished">
36+
<VisualState.Setters>
37+
<Setter TargetName="StartGameArea" Property="IsVisible" Value="False" />
38+
<Setter TargetName="PegSelectionArea" Property="IsVisible" Value="False" />
39+
<Setter TargetName="PegScrollView" Property="IsVisible" Value="True" />
40+
</VisualState.Setters>
41+
</VisualState>
42+
</VisualStateGroup>
43+
</VisualStateManager.VisualStateGroups>
44+
1845
<components:GameResultDisplay Grid.Row="0" />
1946

2047
<FlexLayout
48+
x:Name="StartGameArea"
2149
Grid.Row="1"
2250
MaximumWidthRequest="1500"
2351
Wrap="Wrap"
2452
JustifyContent="Start"
25-
AlignItems="End"
26-
IsVisible="{Binding GameStatus, Mode=OneWay, Converter={StaticResource GameStatusVisibleConverter}, ConverterParameter=Start}">
53+
AlignItems="End">
2754
<VerticalStackLayout
2855
FlexLayout.Basis="500"
2956
Padding="5,0"
@@ -41,8 +68,7 @@
4168
Margin="0,5,0,0"
4269
Padding="5,0"
4370
ColumnDefinitions="*, auto"
44-
MinimumWidthRequest="250"
45-
IsVisible="{Binding GameStatus, Mode=OneWay, Converter={StaticResource GameStatusVisibleConverter}, ConverterParameter=Start}">
71+
MinimumWidthRequest="250">
4672
<Button
4773
Grid.Column="0"
4874
Text="Start the game"
@@ -58,16 +84,15 @@
5884
</FlexLayout>
5985

6086
<components:PegSelectionView
87+
x:Name="PegSelectionArea"
6188
Grid.Row="1"
62-
MaximumWidthRequest="700"
63-
IsVisible="{Binding GameStatus, Mode=OneWay, Converter={StaticResource GameStatusVisibleConverter}, ConverterParameter=Cancelable}"/>
89+
MaximumWidthRequest="700" />
6490

65-
<ScrollView Grid.Row="2" Padding="0,15,0,15" x:Name="pegScrollView" HorizontalOptions="CenterAndExpand">
91+
<ScrollView Grid.Row="2" Padding="0,15,0,15" x:Name="PegScrollView" HorizontalOptions="CenterAndExpand">
6692
<ListView
6793
x:Name="test"
6894
HorizontalOptions="FillAndExpand"
6995
SelectionMode="None"
70-
IsVisible="{Binding GameStatus, Mode=OneWay, Converter={StaticResource GameStatusVisibleConverter}, ConverterParameter=Running}"
7196
ItemsSource="{Binding GameMoves, Mode=OneWay}"
7297
ItemTemplate="{StaticResource PegsTemplate}"/>
7398
</ScrollView>

src/Codebreaker.MAUI/Views/Pages/GamePage.xaml.cs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,47 @@ public partial class GamePage : ContentPage, IRecipient<GameMoveMessage>, IRecip
99
public GamePage(GamePageViewModel viewModel, INavigationService navigationService)
1010
{
1111
_navigationService = navigationService;
12-
BindingContext = viewModel;
13-
InitializeComponent();
12+
ViewModel = viewModel;
13+
InitializeComponent();
14+
BindingContext = viewModel;
1415
WeakReferenceMessenger.Default.RegisterAll(this);
15-
}
16+
ViewModel.PropertyChanged += ViewModel_PropertyChanged;
17+
GoToState("Start");
18+
}
19+
20+
public GamePageViewModel ViewModel { get; }
1621

1722
public async void Receive(GameMoveMessage message)
1823
{
1924
if (message.GameMoveValue is not GameMoveValue.Completed)
2025
return;
2126

2227
await Task.Delay(300);
23-
await pegScrollView.ScrollToAsync(0, pegScrollView.ContentSize.Height, true);
28+
await PegScrollView.ScrollToAsync(0, PegScrollView.ContentSize.Height, true);
2429
}
2530

2631
public async void Receive(InfoMessage message)
2732
{
2833
await DisplayAlert("Info", message.Text, "Close");
2934
}
3035

36+
private void ViewModel_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
37+
{
38+
if (e.PropertyName != nameof(GamePageViewModel.GameStatus))
39+
return;
40+
41+
var stateName = ViewModel.GameStatus switch
42+
{
43+
GameMode.Started or GameMode.MoveSet => "Playing",
44+
GameMode.Won or GameMode.Lost => "Finished",
45+
_ => "Start",
46+
};
47+
GoToState(stateName);
48+
}
49+
50+
private void GoToState(string stateName) =>
51+
VisualStateManager.GoToState(ContentWrapper, stateName);
52+
3153
private async void Button_Clicked(object sender, EventArgs e)
3254
{
3355
await _navigationService.NavigateToAsync("TestPage");

0 commit comments

Comments
 (0)