Reputation: 156
I am working on a UWP app in which my requirement is to show a StackPanel only when Drag is completed in a grid view and condition is met too.
I am making a drag and re-order like game. I want the StackPanel (Containing Result and Buttons) appear when not only a single drag is completed but all the items are sorted too.
I have got everything else working fine. Only StackPanel is problem. It appears just after on drag completed whether the condition is met or not.
Following are the screenshots, code and more briefing !
XAML for GridView
<GridView Name="GameDisplay"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="1"
Grid.Column="1"
CanDrag="True"
CanDragItems="True"
CanReorderItems="True"
SelectionMode="Single"
AllowDrop="True"
DragItemsCompleted="GameDisplay_DragItemsCompleted">
<GridView.ItemTemplate>
<DataTemplate>
<Grid Width="60"
Height="60"
Background="Black">
<TextBlock Text="{Binding}"
FontFamily="BriLliant"
FontSize="48"
FontWeight="light"
Foreground="White"
TextAlignment="Center"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal"
MaximumRowsOrColumns="10"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
XAML For StackPanel
<StackPanel Grid.Row="1" Grid.Column="1" Name="GameFinished" Background="#9900ff" Width="800" HorizontalAlignment="Center" VerticalAlignment="Center" Height="auto">
<Grid Name="InnerGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Name="BtnsContainer" Grid.Column="1" Width="auto" Height="auto" Margin="0 10 0 0">
<Grid Name="BtnsGrid">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="txtBannerType"
Width="auto"
Height="auto"
Grid.Row="0"
Text="Well Done !"
FontSize="72"
FontWeight="Bold"
FontFamily="BriLliant"
Foreground="White"
TextAlignment="Center"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<TextBlock Name="txtTimeSpent"
Width="200"
Height="auto"
Grid.Row="1"
Text=""
FontSize="48"
FontWeight="Light"
FontFamily="BriLliant"
Foreground="White"
TextAlignment="Center"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<TextBlock Name="txtScore"
Width="200"
Height="auto"
Grid.Row="2"
Text="Score : 0"
FontSize="48"
FontWeight="Light"
FontFamily="BriLliant"
Foreground="White"
TextAlignment="Center"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<TextBlock Name="txtBestScore"
Width="200"
Height="auto"
Grid.Row="3"
Text="Best Score : 0"
FontSize="48"
FontWeight="Light"
FontFamily="BriLliant"
Foreground="White"
TextAlignment="Center"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<Button Name="RestartGame"
Width="200"
Height="70"
Grid.Row="4"
Background="Black"
Content="Restart"
FontSize="48"
FontWeight="Bold"
FontFamily="BriLliant"
Foreground="White"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0 20 0 0"
Click="RestartGame_Click"/>
<Button Name="MainMenu"
Width="200"
Height="70"
Grid.Row="5"
Background="Black"
Content="Main Menu"
FontSize="48"
FontWeight="Bold"
FontFamily="BriLliant"
Foreground="White"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0 20 0 0"
Click="MainMenu_Click"/>
</Grid>
</StackPanel>
</Grid>
</StackPanel>
C# Events
private void Page_Loaded(object sender, RoutedEventArgs e)
{
lib.New(GameDisplay);//For Starting New Game
}
private void GameDisplay_DragItemsCompleted(ListViewBase sender, DragItemsCompletedEventArgs args)
{
lib.completed(GameDisplay);//When the tiles are re-ordered
}
Class that is handling BackEnd
class Library
{
//BackEnd for Math Game
private const int size = 5;
private const int total = size * size;
private DateTime timer;
private ObservableCollection<int> items = new ObservableCollection<int>();
private Random random = new Random((int)DateTime.Now.Ticks);
public void show(string content, string title)
{
IAsyncOperation<IUICommand> command = new MessageDialog(content, title).ShowAsync();
}
private List<int> select(int start, int finish, int total)
{
int number;
List<int> numbers = new List<int>();
while ((numbers.Count < total))
{
number = random.Next(start, finish + 1);
if ((!numbers.Contains(number)) || (numbers.Count < 1))
{
numbers.Add(number);
}
}
return numbers;
}
private bool winner()
{
return items.OrderBy(o => o).ToList().SequenceEqual(items.ToList());
}
private void layout(ref GridView grid)
{
timer = DateTime.UtcNow;
grid.IsEnabled = true;
grid.ItemsSource = null;
items = new ObservableCollection<int>();
List<int> numbers = select(1, total, total);
int index = 0;
while (index < numbers.Count)
{
items.Add(numbers[index]);
index++;
}
grid.ItemsSource = items;
}
public void New(GridView grid)
{
layout(ref grid);
}
public void completed(GridView grid)
{
string congo = "";
if (winner())
{
TimeSpan duration = (DateTime.UtcNow - timer).Duration();
congo = string.Format("Time: {0}:{1}:{2}", duration.Hours, duration.Minutes, duration.Seconds);
grid.IsEnabled = false;
}
}
}
Above is the game screen. When I drag and re-order a tile an event is fired in which a method runs until all the tiles are dragged and reordered according to the index of list that is containing all these numbers.
StackPanel only waits for one Drag. Is there any way to add StackPanel into the condition that checks for list sort?? Something like Data-Binding??
If you find anything missing, wrong or the question is already solved before. Please let me know explicitly !
Thanks...
Upvotes: 0
Views: 736
Reputation: 10627
Since you have already use winner()
method to judge whether the game is ended and also invoke this in GameDisplay_DragItemsCompleted
method. So actually the condition is already met in your completed
method (every drag completed to judge whether game is over ). We just need to set the Visibility property of StackPanel
to visible.
Update complete
method as follows:
public void completed(GridView grid,StackPanel stackpanel)
{
string congo = "";
if (winner())
{
TimeSpan duration = (DateTime.UtcNow - timer).Duration();
congo = string.Format("Time: {0}:{1}:{2}", duration.Hours, duration.Minutes, duration.Seconds);
grid.IsEnabled = false;
stackpanel.Visibility = Visibility.Visible;
}
}
Update GameDisplay_DragItemsCompleted
method as follows:
private void GameDisplay_DragItemsCompleted(ListViewBase sender, DragItemsCompletedEventArgs args)
{
lib.completed(GameDisplay,GameFinished);//When the tiles are re-ordered
}
Pay attention that in default the StackPanel
should be collapsed. Update XAML code about StackPanel
as follows:
<StackPanel Grid.Row="1" Grid.Column="1" Name="GameFinished" Background="#9900ff" Width="800" HorizontalAlignment="Center" VerticalAlignment="Center" Height="auto" Visibility="Collapsed">
And you can reset the state for StackPanel
and GridView
when game restart. Code as follows:
private void RestartGame_Click(object sender, RoutedEventArgs e)
{
GameDisplay.IsEnabled = true;
GameFinished.Visibility = Visibility.Collapsed;
}
And the result:
Upvotes: 1
Reputation: 1488
You may create two bool flags and check them in both methods OnDragComplete and OnChangeCondition like this:
private void OnDragComplete()
{
_isDragCompleted = true;
if (_isDragCompleted && _isConditionChanged)
{
CollapseStackPanel();
}
}
private void OnChangeCondition()
{
_isConditionChanged = true;
if (_isDragCompleted && _isConditionChanged)
{
CollapseStackPanel();
}
}
private void CollapseStackPanel()
{
_isDragCompleted = false;
_isConditionChanged = false;
StackPanel.Visibility = Visibility.Collapsed;
}
Upvotes: 1
Reputation: 1490
The problem is, by this code in winner function
return items.OrderBy(o => o).ToList().SequenceEqual(items.ToList()); }
You just check if list items is equal to list items. It will always return true. According to this msdn document orderBy orders the list itself does not return a copy of it.
If you are going to use this method, create another list to compare with curent list and keep that list sorted.
Upvotes: 1