The best overloaded method match has some invalid arguments C# WPF LEAP - c#

Error 1 The best overloaded method match for 'LeapController1.LeapEventListener.LeapEventListener(LeapController1.ILeapEventDelegate)' has some invalid arguments
Error 2 Argument 1: cannot convert from 'LeapController1.MainWindow' to 'LeapController1.ILeapEventDelegate'
I am trying to update the data to the labels on the GUI and i don't know what went wrong.
This is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Leap; //using leap motion library
namespace LeapController1
{
public partial class MainWindow : Window
{
private Controller controller = new Controller();
private LeapEventListener listener;
public MainWindow()
{
InitializeComponent();
this.controller = new Controller();
this.listener = new LeapEventListener(this);
controller.AddListener(listener);
Console.ReadKey(); //prevent console output from closing
controller.RemoveListener(listener); //remove listener from controller
controller.Dispose(); //dispose controller
}
delegate void LeapEventDelegate(string EventName);
public void LeapEventNotification(string EventName)
{
if (this.CheckAccess())
{
switch (EventName)
{
case "onInit":
txtInit.Content = "Initialised";
break;
case "onConnect":
txtConnect.Content = "Connected";
this.connectHandler();
break;
case "onDisconnect":
txtConnect.Content = "Disconnected";
break;
case "onFrame":
txtFrame.Content = " on Frame";
this.movement(this.controller.Frame());
break;
}
}
else
{
Dispatcher.Invoke(new LeapEventDelegate(LeapEventNotification), new object[] { EventName });
}
}//end method LeapEventNotification
public void connectHandler()
{
this.controller.SetPolicyFlags(Controller.PolicyFlag.POLICY_IMAGES);
this.controller.SetPolicy(Controller.PolicyFlag.POLICY_BACKGROUND_FRAMES);
this.controller.EnableGesture(Gesture.GestureType.TYPE_KEY_TAP);
this.controller.EnableGesture(Gesture.GestureType.TYPE_SCREEN_TAP);
this.controller.EnableGesture(Gesture.GestureType.TYPE_SWIPE);
this.controller.EnableGesture(Gesture.GestureType.TYPE_CIRCLE);
this.controller.Config.SetFloat("Gesture.Swipe.MinLength", 100.0f);
}
public void movement(Leap.Frame frame)
{
HandList allHands = frame.Hands; //get hand data array
foreach (Hand hand in allHands) //run for each element in array
{
Leap.Vector normal = hand.PalmNormal; //get hand.PalmNormal data
Leap.Vector direction = hand.Direction; //get hand.Direction data
double pitch = direction.Pitch; //get pitch data
double pitch1 = (pitch) * (180 / Math.PI); //convert rad to deg
int finalpitch = (int)(pitch1); //nearest whole number
double roll = normal.Roll; //get roll data
double roll1 = (roll) * (180 / Math.PI); //convert rad to deg
int finalroll = (int)(roll1); //nearest whole number
txtPitch.Content = finalpitch; //assign data to label
txtRoll.Content = finalroll; //assign data to label
}
GestureList gestures = frame.Gestures(); //returns a list of gestures
for (int i = 0; i < gestures.Count(); i++) //run when gesture made
{
Gesture gesture = gestures[i]; //gesture at that instant
switch (gesture.Type) //check gesture type
{
//if gesture.Type == TYPE_SWIPE
case Gesture.GestureType.TYPE_SWIPE:
txtGesture.Content = "SWIPE";
break;
//if gesture.Type == TYPE_SCREEN_TAP
case Gesture.GestureType.TYPE_SCREEN_TAP:
txtGesture.Content = "SCREEN TAP";
break;
//if gesture.Type == TYPE_KEY_TAP
case Gesture.GestureType.TYPE_KEY_TAP:
txtGesture.Content = "KEY TAP";
break;
//if gesture.Type == neither of the above
default:
txtGesture.Content = "UNKNOWN";
break;
}
}
}
}
public interface ILeapEventDelegate
{
void LeapEventNotification(string EventName);
}
public class LeapEventListener : Listener
{
ILeapEventDelegate eventDelegate;
public LeapEventListener(ILeapEventDelegate delegateObject)
{
this.eventDelegate = delegateObject;
}
public override void OnInit(Controller controller)
{
this.eventDelegate.LeapEventNotification("onInit");
}
public override void OnConnect(Controller controller)
{
this.eventDelegate.LeapEventNotification("onConnect");
}
public override void OnDisconnect(Controller controller)
{
this.eventDelegate.LeapEventNotification("onDisconnect");
}
public override void OnFrame(Controller controller)
{
this.eventDelegate.LeapEventNotification("onFrame");
}
}
}

With this line, you are attempting to create a new LeapEventListener by passing in the current instance of your MainWindow class.
this.listener = new LeapEventListener(this);
There is no constructor for LeapEventListener that takes a MainWindow and there is no way to implicitly convert your MainWindow into a ILeapEventDelegate.
You will need to create a class that implements the interface ILeapEventDelegate. That class will need to implement behavior for the method LeapEventNotification.
Update
Charles Ward noted in a comment to this answer...
There is an example in the Leap Motion docs -- notice that the MainWindow class also implements ILeapEventDelegate.
Looking at the code in the original question, your MainWindow already implements LeapEventNotification method. All you need to do is change your class declaration to explicitly implement the ILeapEventDelegate interface.
public partial class MainWindow : Window, ILeapEventDelegate
{
...

Related

Problems with opening a window - Forms

I'm trying to make a simple 2d game with C# using forms but when i run it at 60 fps it uses 50% of my CPU and doesn't use my GPU at all. I've been looking for hours and can't find another way to do it. How do i get it to run on my GPU?
Also I'm using a thread to wait in between frames with Thread.Sleep(15). I don't know if this is a good way to do it.
I was following this video for the window https://www.youtube.com/watch?v=JnGM1p2vsbE
This is my code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
using System.Drawing;
namespace RadiantEngine
{
class Canvas : Form
{
public Canvas()
{
this.DoubleBuffered = true;
}
}
public abstract class RadiantWindow
{
public Vector2 ScreenSize;
public string Title;
private Canvas Window;
private Thread GameLoopThread;
public float num;
Bitmap image = (Bitmap)Image.FromFile("F:/VS/RadiantEngine/RadiantEngine/dog.png");
public RadiantWindow(Vector2 ScreenSize, string Title)
{
this.ScreenSize = ScreenSize;
this.Title = Title;
EngineInit();
}
public RadiantWindow(float x, float y, string Title)
{
Vector2 _ScreenSize = new Vector2();
this.ScreenSize = _ScreenSize;
this.Title = Title;
EngineInit();
}
void EngineInit()
{
Window = new Canvas();
Window.Text = Title;
Window.Size = new Size((int)ScreenSize.x, (int)ScreenSize.y);
Window.Paint += Renderer;
GameLoopThread = new Thread(GameLoop);
GameLoopThread.Start();
Application.Run(Window);
}
private void Renderer(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.Clear(Color.Aqua);
g.DrawImage(RadiantEngine.engine.renderer.FrameRender(), 0, 0);
}
void GameLoop()
{
OnLoad();
while (GameLoopThread.IsAlive)
{
try
{
OnDraw();
Window.BeginInvoke((MethodInvoker)delegate { Window.Refresh(); });
}
catch
{
Console.WriteLine("Game Is Loading");
}
Thread.Sleep(15);
}
}
public abstract void OnDraw();
public abstract void OnLoad();
}
}
Thanks for any help.

How to modify and show a queue in a WPF c#

I'm trying to show in a TextBox in a Windows Presentation Foundation a queue after adding some items, I know it must be something simple, I've checked the code with a breakpoint, the Add Item button works good but once I press it again the queue is empty and I'm always adding just an item and once I add it and I press the same button Add Item button again or the Show Button the queue is empty, I would like to add items and show the queue with the items I added, I made a class named QueueClas. Here below is all the code, thanks beforehand!!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Queue2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
QueueClas queuec = new QueueClas();
buttonAdd.Click += ButtonAdd_Click;
buttonShow.Click += ButtonShow_Click;
}
private void ButtonShow_Click(object sender, RoutedEventArgs e)
{
QueueClas queuec = new QueueClas();
textBoxShow.Text = queuec.ShowQueue();
}
private void ButtonAdd_Click(object sender, RoutedEventArgs e)
{
QueueClas queuec = new QueueClas();
queuec.AddQueue(int.Parse(textBoxQueue.Text));
textBoxQueue.Clear();
}
public class QueueClas
{
Queue<int> myqueue;
public QueueClas()
{
myqueue = new Queue<int> { };
}
public void AddQueue(int x)
{
myqueue.Enqueue(x);
}
public string ShowQueue()
{
return string.Join(" ", myqueue);
}
public void DeleteItem(int x)
{
myqueue.Dequeue();
}
public string NumberOfItems()
{
int counter = 0;
counter = myqueue.Count();
return "The queue contains " + counter.ToString() + " elements";
}
public string MinQueue()
{
return "The minimun value of the queue is: " + myqueue.Min().ToString();
}
public string MaxQueue()
{
return "The maximum value of the queue is: " + myqueue.Max().ToString();
}
public string FindElement(int x)
{
foreach (int item in myqueue)
{
if (x == item)
{
return "The item is in the queue";
}
}
return "The item is not in the queue";
}
}
}
}
In both the add and show buttons you are initialising your list with QueueClas queuec = new QueueClas();. This is completely erasing the list ans starting fresh. You already initialise it in your MainWindow constructor so there's no need to do it again.

Running a Method from SoundEngine class's object anywhere

I am struggeling with getting my SoundEngine class's function PlaySound to be played where I want it.
The function needs to be a global function but I can't make it static as the function refers to an object that the SoundEngine makes.
I'll show the snippets that are important:
In my GameWorld class:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Input;
using System;
using SoundEngineSpace;
public GameWorld(int width, int height, ContentManager Content)
{
screenWidth = width;
screenHeight = height;
random = new Random();
gameState = GameState.Playing;
block = Content.Load<Texture2D>("block");
font = Content.Load<SpriteFont>("SpelFont");
SoundEffect blockFallSE = Content.Load<SoundEffect>("BlockFallSE");
Song BuildingWallsintheCold = Content.Load<Song>("91 Building Walls in the Cold");
soundEngine = new SoundEngine();
soundEngine.addSound(blockFallSE);
soundEngine.addSong(BuildingWallsintheCold);
soundEngine.SetSoundVolume(20);
soundEngine.SetSongVolume(5);
soundEngine.PlaySong(0);
grid = new TetrisGrid(block);
}
In my TetrisGrid class
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using SoundEngineSpace;
...
public void TetNaarBeneden()
{
soundEngine.PlaySound(0);
InPlayGrid.Velocity = new Vector2(0, gridblock.Height);
CheckValidLocation();
}//Moves tet down
And the soundEngine class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Media;
namespace SoundEngineSpace
{
public class SoundEngine
{
private void soundEngine()
{
}
BackgroundSound backgroundSound = new BackgroundSound();
SoundEffects soundEffects = new SoundEffects();
public void addSong(Song s)
{
backgroundSound.AddBackgroundSound(s);
}
public void addSound(SoundEffect s)
{
soundEffects.AddSound(s);
}
public void PlaySong(int s)
{
backgroundSound.PlayBackgroundSound(s);
}
public void PlaySound(int s)
{
soundEffects.PlaySound(s);
}
public void SetSongVolume(int v)
{
backgroundSound.SetBackGroundSoundVolume(v);
}
public void SetSoundVolume(int v)
{
soundEffects.SetSoundEffectVolume(v);
}
}
}
class BackgroundSound
{
public static void backGroundSound()
{
}
private List<Song> BackgroundSoundEffects = new List<Song>();
private bool PlayingBackGroundSound = false;
public void AddBackgroundSound(Song s)//addsongs to the list
{
BackgroundSoundEffects.Add(s);
}
public void PlayBackgroundSound(int s)//plays BackgroundSound based on location in the list
{
MediaPlayer.IsRepeating = true;//If I use this exact soundengine again, move this to it's own function instead!
if (BackgroundSoundEffects.Count() > s)
{
if (PlayingBackGroundSound)
MediaPlayer.Stop();
MediaPlayer.Play(BackgroundSoundEffects.ElementAt(s));
PlayingBackGroundSound = true;
}
else
{
Console.WriteLine("Couldent find the BackgroundSound");
}
}
public void SetBackGroundSoundVolume(int v)
{
MediaPlayer.Volume = (float)v/100;
}
}
class SoundEffects
{
public static void soundeffects()
{
}
private List<SoundEffect> soundEffects = new List<SoundEffect>();
public void AddSound(SoundEffect s)//addsongs to the list
{
soundEffects.Add(s);
}
public void PlaySound(int s)//plays sound based on location in the list
{
if (soundEffects.Count() > s)
{
SoundEffect ToPlaySound = soundEffects.ElementAt(s);
ToPlaySound.Play();
}
else
{
Console.WriteLine("Couldent find the sound");
}
}
public void SetSoundEffectVolume(int v)
{
SoundEffect.MasterVolume = (float)v/100;
}
}
I ended up making the constructor of objects that needed acces to the SounEngine pass the SoundEngine as a paramter.
Then I could create a new soundEngine within the object I needed it to exsist and call: this.soundEngine = soundEngine.
That succesfully copied the soundEngine and let me use it's fucntions.

Performing calculations using a class and referencing form controls

I am trying to learn classes, meaning writing codes outside of the windows form and calling that code in the form. I created a basic calculation in the form and it works. The problem is, I want to know how I can move the entire calculation into a class and call it into the form on load or when a control is click. It does not work!
Here is my local or form version which works:
Please note that the form will load with the first calculation because the Radiobutton is checked on load.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Calculations
{
public partial class Calculations : Form
{
public Calculations()
{
InitializeComponent();
}
public decimal SalesTax = 0.065M;
public decimal AppliedTax;
public decimal Price;
public decimal SubTotal;
public decimal GrandTotal;
public object Calc()
{
Int32 GetQuantity = Convert.ToInt32(txtQuantity.Text);
SubTotal = (Price * GetQuantity);
AppliedTax = (SubTotal * SalesTax);
GrandTotal = (SubTotal + AppliedTax);
if (radRed.Checked == true)
{
Price = 100;
}
else if (radBlue.Checked == true)
{
Price = 200;
}
else if (radGreen.Checked == true)
{
Price = 300;
}
lblPrice.Text = GrandTotal.ToString("c");
return GrandTotal;
}
private void Calculations_Load(object sender, EventArgs e)
{
txtQuantity.Text = "10";
radRed.Checked = true;
Calc();
}
private void radRed_CheckedChanged(object sender, EventArgs e)
{
Calc();
}
private void radBlue_CheckedChanged(object sender, EventArgs e)
{
Calc();
}
private void radGreen_CheckedChanged(object sender, EventArgs e)
{
Calc();
}
private void btnCalculate_Click(object sender, EventArgs e)
{
Calc();
}
}
}
And here is my attempt to place all of this in a class:
It works but not on load, you have to check another radiobutton first
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Calculations
{
class ClsCalc
{
class ClsRef
{
public static Calculations FormCtrls
{
get
{
return Calculations.ActiveForm as Calculations;
}
}
}
public static decimal SalesTax = 0.065M;
public static decimal AppliedTax;
public static decimal Price;
public static decimal SubTotal;
public static decimal GrandTotal;
public static object Calc()
{
Int32 GetQuantity = Convert.ToInt32(ClsRef.FormCtrls.txtQuantity.Text);
SubTotal = (Price * GetQuantity);
AppliedTax = (SubTotal * SalesTax);
GrandTotal = (SubTotal + AppliedTax);
if (ClsRef.FormCtrls.radRed.Checked == true)
{
Price = 100;
}
else if (ClsRef.FormCtrls.radBlue.Checked == true)
{
Price = 200;
}
else if (ClsRef.FormCtrls.radGreen.Checked == true)
{
Price = 300;
}
ClsRef.FormCtrls.lblPrice.Text = GrandTotal.ToString("c");
return GrandTotal;
}
}
}
Finally I called it in the form Load event:
ClsCalc.Calc();
Please note this is not a real project just a way to learn, well for me that is.
Thank you!
Your calculation method is almost entirely involving interactions with UI elements. You gather a bunch of information from a textbox and various checkboxes, and then have just three lines of actual calculations, and then you display the results.
UI interaction shouldn't be moved outside of the form. You shouldn't expose the internal controls of a form publicly; they should only ever be accessed from within their parent form (or user control, if that's the case).
A common pattern that you'll see when performing some form submit operation is to gather information from input controls, do some calculations on the data, and then display the results on the form. Both the gathering information and displaying results should stay within the form, the only thing that you should (potentially) move outside of the form's definition is the calculations. In this case that's such a small amount of work there just isn't a compelling reason to do that.

C# - OOP - Am I heading along the right track?

First post, long time reader.
I'm currently learning C# with "Head First C#" (I'm up to Encapsulation and Get/Set properties)
I'm writing a small program to work with pictures for a friend, I'm just wondering if I'm heading along the right lines with my PictureController class? My main problem is that I am setting a lot of form items with this class, and it feels unnatured to keep referencing form items from within the class, I'm pasting my code below, if you could let me know if I'm doing anything wrong then I'd be most grateful :)
Many thanks!
PictureController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
namespace PictureController
{
class PictureController
{
private int arrayPosition = 0;
private int numFiles = 0;
private string[,] arrayPictures;
public PictureBox myPictureBox;
public RadioButton myCopyButton;
public RadioButton myDeleteButton;
public TextBox mySource;
public ComboBox myDestinations;
private FolderBrowserDialog sourceFolder;
private FolderBrowserDialog destFolder;
public void InitialisePicture()
{
if (arrayPictures != null && arrayPictures.Length > 0)
{
myPictureBox.ImageLocation = arrayPictures[arrayPosition, 0];
}
else
{
MessageBox.Show("The folder you have selected contains no pictures...");
myPictureBox.ImageLocation = null;
}
}
public void NavigatePicture(int direction)
{
if (arrayPosition + direction >= 0 && arrayPosition + direction < numFiles)
{
arrayPosition += direction;
myPictureBox.ImageLocation = arrayPictures[arrayPosition, 0];
myCopyButton.Checked = Convert.ToBoolean(arrayPictures[arrayPosition, 1]);
myDeleteButton.Checked = Convert.ToBoolean(arrayPictures[arrayPosition, 2]);
}
}
public void UpdateActions(bool copyChecked, bool deleteChecked)
{
if (arrayPictures != null)
{
arrayPictures[arrayPosition, 1] = copyChecked.ToString();
arrayPictures[arrayPosition, 2] = deleteChecked.ToString();
}
}
public void GetFiles()
{
sourceFolder = new FolderBrowserDialog();
sourceFolder.ShowDialog();
if (sourceFolder.SelectedPath != "")
{
string[] arrayTempFiles = Directory.GetFiles(sourceFolder.SelectedPath,"*.jpg");
numFiles = arrayTempFiles.Length;
arrayPictures = new string[arrayTempFiles.Length,3];
for (int i = 0; i < arrayTempFiles.Length; i++)
{
arrayPictures[i, 0] = arrayTempFiles[i];
arrayPictures[i, 1] = "false";
arrayPictures[i, 2] = "false";
}
mySource.Text = sourceFolder.SelectedPath;
InitialisePicture();
}
}
public void AddDestinationFolder()
{
destFolder = new FolderBrowserDialog();
destFolder.ShowDialog();
if (destFolder.SelectedPath != "")
{
myDestinations.Items.Add(destFolder.SelectedPath);
}
}
}
}
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace PictureController
{
public partial class Form1 : Form
{
PictureController PicControl;
public Form1()
{
InitializeComponent();
PicControl = new PictureController() { myPictureBox = pbPhoto, myCopyButton = rbMove, myDeleteButton = rbDelete, mySource = tbSource, myDestinations = cbDestination };
}
private void btnPrev_Click(object sender, EventArgs e)
{
PicControl.NavigatePicture(-1);
}
private void btnNext_Click(object sender, EventArgs e)
{
PicControl.NavigatePicture(1);
}
private void rbMove_CheckedChanged(object sender, EventArgs e)
{
if (rbMove.Checked || rbDelete.Checked)
{
PicControl.UpdateActions(rbMove.Checked, rbDelete.Checked);
}
}
private void rbDelete_CheckedChanged(object sender, EventArgs e)
{
if (rbMove.Checked || rbDelete.Checked)
{
PicControl.UpdateActions(rbMove.Checked, rbDelete.Checked);
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.A:
PicControl.NavigatePicture(-1);
break;
case Keys.D:
PicControl.NavigatePicture(1);
break;
case Keys.W:
rbMove.Checked = true;
break;
case Keys.S:
rbDelete.Checked = true;
break;
}
}
private void btnGetFiles_Click(object sender, EventArgs e)
{
PicControl.GetFiles();
}
private void btnProcess_Click(object sender, EventArgs e)
{
}
private void btnAddDest_Click(object sender, EventArgs e)
{
PicControl.AddDestinationFolder();
}
}
}
I don't see the reason to use Controls in your PictureController class. You should only use non-forms datatypes there and handle the interaction in your Form, offering events and methods from your PictureController class to react and act on it.
It's a good start in my opinion.
Hard to tell if you're doing something "wrong" because it depends what you think is right, every programmer has his/her own style and best practice set and as long as the code is working and efficient it's "right". There are many roads leading to Rome. :)
Anyway if you ask for personal opinion or advice, I would make two major changes in logic:
Have the Controller be a static class (Singleton if you prefer)
Don't pass or use the form controls directly. Instead pass the instance of your form to the static class in some Initialize method, then use that instance and call public method that is working with the controls directly.
Example for the second change:
public static void NavigatePicture(int direction)
{
if (arrayPosition + direction >= 0 && arrayPosition + direction < numFiles)
{
arrayPosition += direction;
_formInstance.SetPictureLocation(arrayPictures[arrayPosition, 0]);
_formInstance.SetCopyStatus(Convert.ToBoolean(arrayPictures[arrayPosition, 1]));
_formInstance.SetDeleteStatus(Convert.ToBoolean(arrayPictures[arrayPosition, 2]));
}
}
//...and in the form:
public SetPictureLocation(sLocation)
{
myPictureBox.ImageLocation = sLocation;
}
What is the point of having the controller, just encapsulate the extra logic out of the form? Do you need your controller to be testable? Do you want to use an abstract model of your business logic? If you answer yes to last 2 questions you might want to google:
a. MVC pattern
b. MVP pattern
Everything is wrong.
Controller (if it is a controller of the form/window) should know about form while in your sample - form know about controller.
Controller should know how to build data / and handle some form events when in your sample controller have references to pictureBox'es etc.
And there are no need to "extract" controller from the control code, while doesn't established what the "data/model" of the control is (and not framed with the type).
It's not clear what is the data there: path or image collection.

Categories

Resources