Login Register
domenica 5 settembre 2010
 
Forums
I Forum di WPF Tips & Tricks
Grid
Last Post 12 lug 2010 10:25 by Gianni Giaccaglini. 2 Replies.
Printer Friendly
Sort:
PrevPrev NextNext
You are not authorized to post a reply.
Author Messages
Max
Basic Member
Basic Member
Posts:13
Avatar

--
03 lug 2010 10:40  
Non è da molto che mi sono messo a lavorare con le wpf, ora stavo cercando di creare un progetto che mi permettesse di famigliarizzare un po con questa tecnologia.

Ho pensato di creare il gioco del "Tris" , croci e cerchietti, all'apparenza niente di più semplice, ma mi sono bloccatto immediatamente.

Senza progettare le classi e niente mi sono messo subito a fare un po di test singoli, e ho provato a dividere una griglia in 9 parti, ho inserito ShowGridLines="True" in modo da vedere come era divisa la griglia.

Sucessivamente ho aggiunto una colonna e una label.

Ho scritto questa riga di codice qui:

Private Sub Grid1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseEventArgs) Handles Grid1.MouseMove
Label9.Content = e.GetPosition(Grid1).ToString
End Sub

Quindi, molto teoricamente nel momento in cui muovo il mouse all'interno della Grid1 dovrei avere le coordinate formato stringa sulla mia label... giusto?

Invece no, se all'interno della grid e nelle varie celle inserisco un qualunque controllo, tipo un label o una textbox, allora mi appaiono le coordinate del mouse, ma solamente nel caso che passo sopra agli stessi controlli.

Non ho capito che cosa mi sfugga, non dovrebbe funzionare come un panel? perchè la grid è trasparente in questo senso?

Se doveste fare il medesimo progetto che tipo di panel usereste? e perchè?

Grazie

Marco
Roberto Sarati
Basic Member
Basic Member
Posts:32
Avatar

--
03 lug 2010 01:42  
Non ricordo esattemnte il perchè... però mi pare che impostando sulla griglia Background=Transparent ti risolva il problema.

Comunque, sempre che non sia un problema, userei una griglia dove, in ogni cella c'è un controllo [che poi ti disegnerà una X o un O] dove quindi hai gli eventi dell'oggetto e la posizione degli stessi.
Il problema è che altrimenti dovresti trovare la cella (#riga e #colonna) da una posizione relativa... si può fare ma io punto sulla semplicità.
Gianni Giaccaglini
Basic Member
Basic Member
Posts:41
Avatar

--
12 lug 2010 10:25  
GIANNI GIACCAGLINI (giannigiac@tin.it)
Con cordo con la replice dell'ottimo Roberto Sarati. Pertanto credo che il Gioco del Tris presente in sostanza analogia con altri consimili, come il ben noto GIOCO DEL 15. Così mi permetto di indicare una possibile implementazione di quest'ultimo, ritenendo che, mutatis mutandis, possa adattarsi anche al TRIS.

Il gioco del 15 si potrebbe implementare definendo in una Grid di 4 x 4 celle una serie di 15 pulsanti etichettati, non a caso, da 1 a 15, più una cella-buco, destinati ad essere spostati a run-time, con istruzioni del tipo SetValue(Grid.RowProperty, ColonnaBuco) e SetValue(Grid.ColumnProperty, RigaBuco) nel buco posto inizialmente nella cella a destra in basso.

CODICE XAML
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Gioco del 15" Height="300" Width="300">
<Grid Name="Grid1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100*" />
<ColumnDefinition Width="100*" />
<ColumnDefinition Width="100*" />
<ColumnDefinition Width="100*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40*" />
<RowDefinition Height="40*" />
<RowDefinition Height="40*" />
<RowDefinition Height="40*" />
</Grid.RowDefinitions>
<Button Margin="10" Name="Button1" Click="SpostaPulsante" Grid.Row="0" Grid.Column="0" FontSize="16" BorderThickness="5" Foreground="Chocolate">
10
</Button>
<Button Margin="10" Name="Button2" Click="SpostaPulsante" Grid.Row="0" Grid.Column="1" Background="Blue" FontSize="16" BorderThickness="5" Foreground="White">
6
</Button>
. . . OMISSIS . . .
</Button>
<Button Margin="10" Name="Button15" Click="SpostaPulsante" Grid.Row="3" Grid.Column="2" Background="Blue" FontSize="16" BorderThickness="5" Foreground="White">
6
</Button>
</Grid>
</Window>

Commenti essenziali. I 15 Button hanno nomi che vanno da “Button1” a “Button2” fino a “Button15, con gli OMISSIS relativi a quelli da Button3 a Button14. Facile notare che le proprietà Grid.Row e Grid.Column procedono dalla coppia 0,0 a 0,1 ecc. fino a 3,2, mentre il buco sta nella cella 3,3.
Ancor più importante da sottolineare: la proprietà Click=”SpostaPulsante” accomuna tutti i 15 Button, il che consente di essere richiamata una volta sola:
Private Sub SpostaPulsante(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Dim Riga As Integer, Colonna As Integer
Riga = sender.GetValue(Grid.RowProperty)
Colonna = sender.GetValue(Grid.ColumnProperty)
If Riga = RigaBuco And System.Math.Abs(Colonna - ColonnaBuco) = 1 Then
sender.SetValue(Grid.ColumnProperty, ColonnaBuco)
ColonnaBuco = Colonna
ElseIf Colonna = ColonnaBuco And System.Math.Abs(Riga - RigaBuco) = 1 Then
sender.SetValue(Grid.RowProperty, RigaBuco)
RigaBuco = Riga
End If
If FineGioco() = True Then
MessageBox.Show("Gioco concluso")
End If
End Sub

Nota. Visto che sender nel nostro caso è sempre un pulsante si potrebbe sostituirne la definizione con sender As Button. Così l’intellisense restituirebbe le proprietà occultate dal troppo generale tipo System.Object.

L’agoritmo spero sia chiaro. Consiste nel controllare se la riga del pulsante corrente è la stessa del buco nonché se la colonna differisce di una sola unità, nel qual solo caso si invertono i ruoli del pulsante corrente col buco, semplicemente agendo sulle rispettive proprietà Grid.RowProperty e Grid.ColumnProperty.

Dimenticavo la parte alta del modulo VB. Eccola:
Class Window1
Dim RigaBuco As Integer = 3
Dim ColonnaBuco As Integer = 3
Dim VettRighe() As Integer = _
{0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3}
Dim VettColonne() As Integer = _
{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3}

Function FineGioco() As Boolean
Dim i = 0, NumContent = 0
Dim Riga = 0, Colonna = 0
For Each Puls As Button In Grid1.Children
Riga = Puls.GetValue(Grid.RowProperty)
Colonna = Puls.GetValue(Grid.ColumnProperty)
NumContent = CType(Puls.GetValue(ContentProperty), Integer) - 1
If Not (VettRighe(NumContent) = _
Riga And VettColonne(NumContent) = Colonna) Then
Return False
End If
Next
Return True
End Function

Sub SpostaPulsante(ByVal Puls As Button)
Eccetera eccetera.

A buon intenditore…

giannigiac@tin.it
You are not authorized to post a reply.

Active Forums 4.2
  
 
© 2009-2010 WPF Tips&Tricks Team - Visual Basic Tips&Tricks Network