Usuwanie przycisku utworzonego dynamicznie

0

Witam. Robię w WPF warcaby i mam problem z usunięciem pionka, którego zbijam. Każdy z pionków oraz puste pola są przyciskami. Najlepiej wyjaśnię to na przykładzie.
Chcę ruszyć się białym pionkiem zgodnie z narysowaną strzałką, czyli zbić czarnego pionka.
titlehttps://ibb.co/cvhuzb
W tym celu klika myszką na białego pionka, którym chcę się ruszyć i drugi raz klikam myszką w puste pole gdzie chce postawić mojego białego pionka. Efekt tego jest taki:
titlehttps://ibb.co/fr22Kb
Czyli biały pionek idzie tam gdzie prawidłowo ma iść, natomiast czarny powinien się usunąć i w jego miejscu powinien pojawić się przycisk z niewidocznym tłem i konturami oraz napis "0".
Teraz przedstawię kod.
round.xaml.cs - tutaj wypełniam tablicę round_table moimi przyciskami z pierwszym graczem, pustymi polami i drugim graczem. Następnie dodaje każdy przycisk do "grid" - nazwa siatki wpisana na sztywno w XAMLu. Wstawiam tylko wypełnienie pionków dla czarnych pionków, reszta jest analogicznie.

public void set_checker()
{            
            for(int i=0;i<=2;i++)//second player
            {
                for(int j=0;j<=7;j++)
                {
                    if (i == 1)
                    {
                        round_table[i, j] = warcab.create_warcab(i, j, 2);

                        grid.Children.Add(round_table[i, j]);
                        j++;
                    }
                    else
                    {                       
                            j++;
                        if (j == 8) { }
                        else
                        {
                            round_table[i, j] = warcab.create_warcab(i, j, 2);
                            grid.Children.Add(round_table[i, j]);
                        }
                    }
                }
            }
}

warcab.cs

public  Button create_warcab(int i,int j,int player)
{
            string p1_skin = "files/p1.png";
            string p2_skin = "files/p2.png";
            Thickness _margin = get_coordinate(i, j);
            Button button = new Button();
            
            if (player==2)
            {
                button.Margin = _margin;
                button.Content = player.ToString();
                button.Width = 34;
                button.Height = 34;
                button.Name = "button_" +i.ToString() + j.ToString();
                button.Background = new ImageBrush { ImageSource = new BitmapImage(new Uri(p2_skin, UriKind.Relative)) };
                button.BorderBrush = new SolidColorBrush(Colors.Transparent);
                button.AddHandler(Button.ClickEvent, new RoutedEventHandler(Nbutton_Click));              
               
            }
return button; 
//dla pionków czarnych, wypełnianie przycisków dla drugiego gracza i tych z pustymi polami jest analogicznie, tylko player==0 i 2
}
 public Thickness get_coordinate(int i,int j)
 {
            Margin = new Thickness();

            if ((i == 0) && (j == 1))
            {
                Margin = new Thickness(68, 20, 315, 502);
            }
.
i tak dalej...
.
          return Margin;
// czyli na sztywno definiuje gdzie na obrazku z szachownicą mają leżeć pionki
}

//a teraz funkcja która jest uchwytem i działa tylko wtedy gdy użytkownik naciśnie konkretny przycisk, czyli pionek
 public void Nbutton_Click(object sender, EventArgs e)
{
            click_counter++;
            if (click_counter == 1)
            {
                Button tmp_button1 = sender as Button;
                click_table[0] = tmp_button1;
            }
            else
            {
                Button tmp_button2 = sender as Button;
                click_table[1] = tmp_button2;
               
                click_counter = 0;
                string player_1_or_2 = click_table[0].Content.ToString();
                
                Thickness tmp_margin1 = WARCAB.click_table[0].Margin;
                int i_position = int.Parse(click_table[0].Name.Substring(7, 1));
                int j_position = int.Parse(click_table[0].Name.Substring(8, 1));
                int i_position_target = int.Parse(click_table[1].Name.Substring(7, 1));
                int j_position_target = int.Parse(click_table[1].Name.Substring(8, 1));
 // click_table zbiera z którego do którego przycisku chcę iść i dalej są różne funkcje sprawdzające czy mogę wykonać dany ruch I następnie:
 swap(tmp_margin1, i_position, j_position, i_position_target, j_position_target);    // zamieniam miejscami przycisk z pionkiem z moim przyciskiem emitującym puste pole, ta funkcja działa dobrze.            
ROUND.round_table[i_position - 1, j_position + 1] = create_warcab(i_position - 1, j_position + 1, 0); // teraz  między nimi został czarny pionek do zbicia.Więc w miejsce tablicy w którym znajduje się ten pionek do zbicia tworzę (czyli nadpisuję) nowy przycisk.
       
 private static void swap(Thickness tmp_margin1, int i_position, int j_position, int i_position_target, int j_position_target) //ta funkcja zamienia mi puste pole z  pionkiem
 {
            click_table[0].Margin = click_table[1].Margin;
            click_table[1].Margin = tmp_margin1;
            ROUND.round_table[i_position, j_position] = click_table[1];
            ROUND.round_table[i_position_target, j_position_target] = click_table[0];
            ROUND.round_table[i_position, j_position].Content = click_table[1].Content;
            ROUND.round_table[i_position_target, j_position_target].Content = click_table[0].Content;
            ROUND.round_table[i_position, j_position].Name = "button_" + i_position.ToString() + j_position.ToString();
            ROUND.round_table[i_position_target, j_position_target].Name = "button_" + i_position_target.ToString() + j_position_target.ToString();
 }

Jak widać na przykładzie funkcji swap

 click_table[0].Margin = click_table[1].Margin;
click_table[1].Margin = tmp_margin1;

takie coś spowodowało, że podczas pracy programu udało się zamienić ze sobą pionek z pustym polem. Jednak funkcja swap() działa dla tego, że kliknąłem na konkretne przyciski, które się zmieniły. Jak odwołać się do przycisku pomiędzy nimi ? Czyli czarnym pionkiem, którego muszę usunąć lub napisać ?

0

Jeśli pisanie tego w ten sposób sprawia Ci przyjemność to nie czytaj dalej mojego postu bo nie chcę Ci psuć zabawy.

Myślałeś może nad tym czy nie dałoby się tego zrobić prościej niż to robisz w obecny sposób? Np przez oddzielenie interfejsu od logiki/stanu gry, użyciu bindingów.
Nie fajniej by było mieć jedną tablicę dwuwymiarową w której miałbyś stan poszczególnych pól i na nim operował : ChessBoard[2][4].State = CellState.Player1Pawn
Bo w obecnej chwili tworzysz jedna wielką kupę ... spaghetti.

0

Może na początek poczytaj o kontrolce Grid, jak utworzyc siatke - klasach ColumnDefinition, RowDefinition, metodach Grid.SetColumn, Grid.SetRow, Grid.GetColumn, Grid.GetRow.
Usunąć kontrolkę jest najprościej: grid.Children.Remove() ,

0

próbowałem children.remove(), jednak funkcja set_checker() w której używam grida, od razu po skończeniu powoduje, że nie mogę dostać się do mojego grida, ponieważ wszystko co jest w funkcji żyje tylko w niej.
Istnieje możliwość przekazania mojego grida poza granice funkcji set_checker() nawet do zupełnie innej klasy ?
Jeżeli stworzę mojego grida (który w tym przypadku jest obrazkiem z szachownicą) w kodzie a nie XAMLu to raczej powinienem móc potem przekazać grida do kolejnych funkcji ?

0

Przecież ten grid nie jest ograniczony do funkcji set_checker() , bo nigdzie go nie tworzysz wewnątrz niej, tylko gdzieś wcześniej

0

Nie wiem czy chodzi Ci o określenie współrzędnych czy o pobranie samego przycisku.
Jeśli pierwsze to (chyba) (x1+x2)/2 i odpowienio dla y powinno dac w kzsym przypadku wpsolrzedne zbitego pola. Jesli o samo pobranie obiektu Burton to nie wiem bo misie nawet nie chce czytać gdzie to przechowujesz. Przepraszam. No ale jak masz jakąś tablicę z przyciskami to chyba tam powinny być.

1 użytkowników online, w tym zalogowanych: 0, gości: 1