Jump to content
bambosz

C# - przesuwanie obiektów w oknie ?

Recommended Posts

Hej,

 

postanowiłem co nieco posiedzieć w C# (visual studio).

 

Aktualnie próbuję zmajstrować coś na kształt aranżatora pokoi / sal.

Wszystko ładnie śmiga.

 

Mam już:

Główne okno programu (otwiera dodatkowe okna z salami)

W oknie sali:

- prawy klik otwiera menu z opcjami (dodawania stoliczków, "sceny", "podestu", baru, itp.)

- prawy klik zamykanie aktualnego planu

- prawy klik zapis aktualnego planu do pliku PDF

 

Jedyny problem jaki na tę chwile mnie męczy to dodanie do obiektów możliwości przesuwania ich po dodaniu ich do sceny.

Kod dodawania nowego stoliczka jest banalnie prosty:

 

           myPictureBox stolik4 = new myPictureBox();                                           //utworzenie nowego obiektu klasy myPictureBox dziedziczącego po PictureBox (przymiarka do rozszerzenia o przemieszczanie obiektów)
           stolik4.Image = Image.FromFile("../../Resources/stolik4" + ".png");          //ustawienie obrazka dla pictureBox
           stolik4.Location = getMousePosition();                            //tu wywołana jest funkcja pobierająca pozycje kursora 
           stolik4.Width = 40;
           stolik4.Height = 40;                                                     // wys, szer. pola obrazka
           Controls.Add(stolik4);                                           // dodanie obrazka do "sceny"
           stolik4.BringToFront();                                           //wyciagniecie nowego obrazka na wierzch 

 

 

No i tu jest problem - jak to zrobić, żeby te nowe obiekty (tu stoliczki) można było przesuwać po kliknięciu ich myszką ...

Jest tu ktoś, kto ogarnia C# dla windows application ?

Share this post


Link to post
Share on other sites

Dawno nie siedzialem w windows a tym bardziej w visualu wiec podam troche ogolne tipy.

 

Widze ze robi w Win Forms, wiec - kazda kontrolka ma eventy - na pewno masz event na drag.

 

https://msdn.microsoft.com/en-us/library/aa984430(v=vs.71).aspx

 

Accomplishing drag-and-drop operations within Windows applications is done via the handling of a series of events, most notably the DragEnter, DragLeave, and DragDrop events. By working with the information available in the event arguments of these events, you can easily facilitate dragging and dropping.

 

Ciebie interesuje DragEnter i DragLeave lub DragDrop.

 

Sprawdz czy kontolka ma jakis checkbox (bool) typu dragable lub cos podobnego. Potem pewnie wystarczy w handlarze eventa DragDrop odczytac pozycje kursora i nadac kontrolce nowa pozycje.

Share this post


Link to post
Share on other sites

bolitic

 

pod zwykłym pictureBox'em już działa.

Trochę koślawo (obrazek przeskakuje w miejsce kursora po puszczeniu go ;)

public bool moveDetect = false;

       private void pictureBox4_MouseDown(object sender, MouseEventArgs e)
       {
           moveDetect = true;
       }

       private void pictureBox4_MouseMove(object sender, MouseEventArgs e)
       {
           if (moveDetect)
           {
               Point pozycja = new Point();
               this.Cursor = new Cursor(Cursor.Current.Handle);
               pozycja = this.PointToClient(Cursor.Position);
               pictureBox4.Location = pozycja;
           }
       }

       private void pictureBox4_MouseUp(object sender, MouseEventArgs e)
       {
           if (moveDetect)
           {
               moveDetect = false;
           }
       }

 

Teraz tylko pytanie, jak to przenieść na wszystkie utworzone obiekty :/

Na 1 obrazek dodany do sceny ręcznie działa pięknie. Tylko jak taką funkcję przypisać do wszystkich utworzonych obiektów ? ;D

Edited by bambosz

Share this post


Link to post
Share on other sites

Bardzo prosto. Stworz generyczne handelry eventow (np nie "pictureBox4_MouseMove" ale "control_MouseMove"), a potem gdy masz utowrzony nowy obiket/kontrolke to bierzesz ten obiekt i "controller.OnMouseMove += control_MouseMove" (Nie wiem czy taka nazwa eventu jest wiec sprawdz). Potem w tym handlerze masz parameter "sender" = to powinien byc ten obiekt kontrolki. Wiec rzutujesz ten obiekt sender na typ kontroli i zmieniasz pozycje.

Share this post


Link to post
Share on other sites

bolitic

 

 

Jako nie-programista kompletnie nie mam pojęcia o czym do mnie piszesz ale znalazłem wczoraj wieczorkiem takie coś:

 

Działać działa - tylko przy ruchu myszy jakby kopiowało obrazek i robi takiego ... węża ;D

Ale jest postęp ;p

 

Dostosowałem to do swojego kodu (męczę się taraz z "this.MouseMove..."

całą funkcję dołączam do obiektu w czasie tworzenia go.

 

Nie wiem dlaczego, ale nadal, nie dość że robi węża, to teraz jeszcze jakby dzieli ruch obrazka na pół względem kursora :/

Kursor jedzie 400 px w prawo a obrazek mniej (około 200) :/

 

public void moveFunction()
       {
           this.MouseDown += (ss, ee) =>
           {
               if (ee.Button == System.Windows.Forms.MouseButtons.Left)
               {
                   moveDetect = true;

               }

           };

           this.MouseMove += (ss, ee) =>
           {
               if (moveDetect)
               {
                   Point pozycja = new Point();
                   this.Cursor = new Cursor(Cursor.Current.Handle);
                   pozycja = PointToClient(Cursor.Position);
                   this.Location = pozycja;
               }
           };

           this.MouseUp += (ss, ee) =>
           {
               moveDetect = false;
           };

       }

Edited by bambosz

Share this post


Link to post
Share on other sites

Już wiem z kąd problem z przesuwaniem obiektów ;D

 

C# widzi ruch myszy tylko nad danym obiektem.

Jeśli chcę odczytać pozycję kursora nad oknem jest ok, do czasu aż nad oknem nie ma innego obiektu (np. picturebox. label, itp). Wtedy wartość nie jest pobierana :/

 

Pytanie jak to obejść :/

Share this post


Link to post
Share on other sites

Nie wiem szczerze osobiscie - moze w gre wchodzi lokalne/globalne wartosci?

 

Te 4 linie kodu mozesz zapisac w jednej:

 

Point pozycja = new Point();
this.Cursor = new Cursor(Cursor.Current.Handle);
pozycja = PointToClient(Cursor.Position);
this.Location = pozycja;

 

=

 

this.Location = PointToClient(new Cursor(Cursor.Current.Handle).Position);

 

Poza tym masz bardzo zle podejscie do kodowania - kodowanie wymaga duzo samodzielnosci i znajomosci podstaw (takich na przyklad jak terminy, ktorych powiedziales nie rozumiesz). W internecie w dzisiejszych czasach az buzuje od dokumentacji, tutoriali, artykolow, wiki, google - tam znajdziesz odpowiedz i wiedze. Pytanie na forum (zreszta w 99% dla artystow) jak rozwiazac podstawowe problemy nie jest dobra droga na rozwoj :)

Share this post


Link to post
Share on other sites

bolitic

 

i właśnie w weekend sprawę rozwiązałem w banalny sposób ;]

 

W klasie "stoliczka" zmienna globalna

 

"public static Point mousePosition;"

 

W klasie / Formie z planem sali:

 

private void timer1_Tick(object sender, EventArgs e)

{

mouseLocation = PointToClient(Control.MousePosition); //PointToScreen

myPictureBox.mousePosition = mouseLocation;

}

 

W ten oto sposób problem przekazania pozycji myszy do obiektów (stoliczków) został rozwiązany a aplikacja działa ;D

 

Wiem że to nie najlepszy sposób z pytaniem na forum, ale uwierz lub nie - zawsze gdy zadam pytanie "10 min" później znajduje rozwiązanie ;D

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

We are using cookies. Read about our Privacy Policy