Ja dein Lösungsansatz ist auch nicht besonders effizient
Ich versteh allerdings nichts von VB und benutz C# in diesem Beispiel.
Mein Ansatz ist folgender:
Ich hab mir ein Canvas Element auf mein Fenster gepackt und horche einfach auf das MouseLeftButtonDown-Event (MouseLeftButtonUp geht auch, ist hier aber nicht relevant).
Im Eventhandler lese ich dann die momentanen Maus-Koordinaten relativ zum Canvas-Element aus. Somit weiß ich schonmal, wo sich die Maus innerhalb meines Canvas befindet.
Nun muss ich wissen, wie groß ein Block ist. Ich hab jetzt einfach mal deine 10x10 Größe genommen (kann aber auch beliebig variiert werden und kann natürlich auch asymmetrisch sein).
Nun muss berechnet werden, in welchem Block ich mich befinde.
Dazu berechne ich quasi die obere linke Ecke des Blocks.
Das erreiche ich, in dem ich die momentane X-Koordinate durch die Blockbreite und die Y-Koordinate durch die Blockhöhe teile und jeweils beide Ergebnisse abrunde.
Hierbei bitte beachten, dass ich im Prinzip mit Indizes arbeite die bei 0 beginnen (sprich (0,0) -> erster Block in der ersten Zeile, (1,3) -> zweiter Block in der vierten Zeile).
Anschließend muss man nur noch ein Rechteck mit den entsprechenden Blockmaßen erstellen und den linken und oberen Abstand innerhalb des Canvas setzen.
Den linken und oberen Abstand wird errechnet, in dem man die beiden Indizes des Blocks mit Höhe bzw Breite des Blocks multipliziert.
Wenn du z.B. den dritten Block in der fünften Zeile setzen willst, dann hättest du folgende Rechnung (mit anderer Blockgröße zur Verdeutlichung):
Code:
Block Indizes -> (2,4)
Blockbreite -> 10px
Blockhöhe -> 15px
Linker Abstand -> 2*10 = 20px
Oberer Abstand -> 4*15 = 60px
Zum Setzen der Abstände benutzt man dann die Methoden Canvas.SetTop und Canvas.SetLeft.
Der Code sollte eigentlich nicht allzu schwer zu verstehen sein und die Methoden sind glaub ich auch größtenteils identisch in VB, von daher sollte es kein Problem sein den C# Code zu porten.
Im Quellcode sind ein paar Extras, wie z.B. die Anzeige der Koordinaten oder des aktuellen Blocks. Sowas kannst du ignorieren.
Und ja es ist auch kein richtiges MVVM (für alles die wissen was das ist) was ist da fabriziere, aber mir ist dieses Pseudo-MVVM bei dem Beispiel lieber.
(MVVM = Model-View-ViewModel)
Im Anhang ist der Quellcode zu meinem Beispiel wo eventuell die ganze Erklärung hier ein wenig besser verständlich ist

In der .zip findest du auch eine .exe Datei des Programms, aber kannst es dir ja auch selbst nochmal compilen.
Virustotal zur Exe: