Korzystanie z obiektu XAML w metodach

0

Witam
Dopiero zaczynam uczyć się programowania w C# i mam problem z dostępem do obiektów utworzonych w XAML.

Klasa która tworzy prostokąty i ma je wyświetlić na obiekcie Canvas który utworzyłem w XAML wyrzuca błąd:

Cannot access a non-static member of outer type 'WpfApplication2.MainWindow' via nested type 'WpfApplication2.MainWindow.Gracz'

<Grid>
    <Canvas x:Name="canv" HorizontalAlignment="Left" Height="263" Margin="10,10,0,0" VerticalAlignment="Top" Width="371"/>
</Grid>
public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Gracz gr1 = new Gracz();
            gr1.wyswietl();
        }

        public class Gracz
        {
            const int ile = 10;
            private Rectangle[] rec;

            public Gracz()
            {
                this.rec = new Rectangle[ile];
                for (int y = 0; y < ile; ++y)
                    rec[y] = new Rectangle { Width = 90, Height = 125 };

            }

            public void wyswietl()
            {
                for (int y = 0; y < ile; ++y)
                {
                    Canvas.SetTop(rec[y], 10);
                    Canvas.SetLeft(rec[y], 10 + y * 45);
                    canv.Children.Add(rec[y]);
                }
            }

        }
        
    }

Mógłby ktoś coś poradzić?

1

Przekaż obiekt Canvas - canv - do klasy Gracz jako parametr konstruktora.

0

Ok, do wyświetlania rozumiem, zmodyfikowałem kod aby działał, ale teraz znowu mam podobny problem - nie wiem jak mam przekazać Canvas do eventu...

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Gracz gr1 = new Gracz();
            gr1.wyswietl(canv);
             
        }
     
            
        

        public class Gracz
        {
            const int ile = 10;
            private Rectangle[] rec;

            bool captured = false;
            double x_shape, x_canvas, y_shape, y_canvas;
            double xStart, yStart;
            UIElement source = null;
            Point p;


            public Gracz()
            {
                this.rec = new Rectangle[ile];
                for (int y = 0; y < ile; ++y){
                    rec[y] = new Rectangle { Width = 90, Height = 125 , Stroke = Brushes.Black};
                    rec[y].MouseLeftButtonDown += zlap;
            }
            }

            public void wyswietl(Canvas canv)
            {
                for (int y = 0; y < ile; ++y)
                {
                    Canvas.SetTop(rec[y], 10);
                    Canvas.SetLeft(rec[y], 10 + y * 45);
                    
                    canv.Children.Add(rec[y]);
                }
            }
            private void zlap(object sender, EventArgs e)        ///mouse left button down
            {
                source = (UIElement)sender;
                Mouse.Capture(source);
                captured = true;
                p = Mouse.GetPosition(canv);
                xStart = x_shape = Canvas.GetLeft(source);
                x_canvas = p.X;
                yStart = y_shape = Canvas.GetTop(source);
                y_canvas = p.Y;

            }

        }
        
    }
1

Skoro używasz obiektu Canvas w kilku metodach jednej klasy, to najlepiej byś trzymał referencję do niego jako pole tej klasy (nie będziesz musiał wtedy przekazywać go do każdej metody).

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Gracz gr1 = new Gracz(canv);
            gr1.wyswietl();
 
        }
 
 
 
 
        public class Gracz
        {
            const int ile = 10;
            private Rectangle[] rec;
 
            bool captured = false;
            double x_shape, x_canvas, y_shape, y_canvas;
            double xStart, yStart;
            UIElement source = null;
            Point p;

            **Canvas canvas;**
 
 
            **public Gracz(Canvas canv)**
            {
                **canvas = canv;**
                this.rec = new Rectangle[ile];
                for (int y = 0; y < ile; ++y){
                    rec[y] = new Rectangle { Width = 90, Height = 125 , Stroke = Brushes.Black};
                    rec[y].MouseLeftButtonDown += zlap;
            }
            }
 
            **public void wyswietl()**
            {
                for (int y = 0; y < ile; ++y)
                {
                    Canvas.SetTop(rec[y], 10);
                    Canvas.SetLeft(rec[y], 10 + y * 45);
 
                    **canvas.Children.Add(rec[y]);**
                }
            }
            private void zlap(object sender, EventArgs e)        ///mouse left button down
            {
                source = (UIElement)sender;
                Mouse.Capture(source);
                captured = true;
                **p = Mouse.GetPosition(canvas);**
                xStart = x_shape = Canvas.GetLeft(source);
                x_canvas = p.X;
                yStart = y_shape = Canvas.GetTop(source);
                y_canvas = p.Y;
 
            }
 
        }
 
    }

Przeniosłem przekazanie Canvas do konstruktora, gdzie zapisuje go jako pole klasy Gracz - od tej pory mogę używać go w każdej metodzie klasy.

Alternatywnie możesz zrobić tak:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            **Gracz gr1 = new Gracz(canv);**
            gr1.wyswietl(canv);
 
        }
 
 
 
 
        public class Gracz
        {
            const int ile = 10;
            private Rectangle[] rec;
 
            bool captured = false;
            double x_shape, x_canvas, y_shape, y_canvas;
            double xStart, yStart;
            UIElement source = null;
            Point p;
 
 
            public Gracz(Canvas canv)
            {
                this.rec = new Rectangle[ile];
                for (int y = 0; y < ile; ++y){
                    rec[y] = new Rectangle { Width = 90, Height = 125 , Stroke = Brushes.Black};
                    **rec[y].MouseLeftButtonDown += (s, e) => zlap(s, e, canv);**
            }
            }
 
            public void wyswietl(Canvas canv)
            {
                for (int y = 0; y < ile; ++y)
                {
                    Canvas.SetTop(rec[y], 10);
                    Canvas.SetLeft(rec[y], 10 + y * 45);
 
                    canv.Children.Add(rec[y]);
                }
            }
            **private void zlap(object sender, EventArgs e, Canvas canv)**        ///mouse left button down
            {
                source = (UIElement)sender;
                Mouse.Capture(source);
                captured = true;
                p = Mouse.GetPosition(canv);
                xStart = x_shape = Canvas.GetLeft(source);
                x_canvas = p.X;
                yStart = y_shape = Canvas.GetTop(source);
                y_canvas = p.Y;
 
            }
 
        }
 
    }

Tutaj także przekazuje canv do konstruktora, ale tym razem nie zapisuje go w sposób jawny.

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