Coloring text using reflection - c#

I'm trying to make a simple text editor that colors text in real time. I also must use DLL and Reflection for this.
I want to color the text while user typing. For that reason I have a checkbox. If it checked the text will be colored while user is typing (Real Time).
I've wrote a DLL file to do that.
Anyway, I'm very new to reflection thing.
The question:
I would want to ask you guys for your professional advice whether what I've wrote can be called "using reflection" or not? and if it's not, can point me what is wrong?
Here is my code (I've removed many things from it so the code will reflect the question but there might be leftovers)
using System;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Reflection;
namespace Editor
{
public class MainForm : Form
{
//Declaration of Controls
private RichTextBox EditRichTextBox;
private CheckBox chkBox;
private int flag = 0;
private Button[] PlugButton;
public string[] PluginNames;
private int NumofPlugins;
public MainForm()
{
//Initialization of Controls
this.EditRichTextBox = new RichTextBox();
this.ErrorTextBox = new RichTextBox();
this.chkBox = new CheckBox();
//Form
this.ClientSize = new Size(700, 500);
this.Name = "MainForm";
this.Text = "C# Editor";
//EditRichTextBox
this.EditRichTextBox.Location = new Point(20, 20);
this.EditRichTextBox.Name = "EditRichTextBox";
this.EditRichTextBox.Size = new Size(this.Width - 150, 300);
this.EditRichTextBox.AcceptsTab = true;
this.EditRichTextBox.Multiline = true;
//Controls on the Form
this.Controls.Add(this.ButtonCompilelib);
this.Controls.Add(this.ButtonCompile);
this.Controls.Add(this.ButtonRun);
this.Controls.Add(this.EditRichTextBox);
this.Controls.Add(this.ErrorTextBox);
this.Controls.Add(this.chkBox);
//CheckBox
this.chkBox.Location = new Point(600,300);
this.chkBox.Name = "chkBox";
this.chkBox.Text = "Color";
};
//My checkbox handler
this.chkBox.Click += (sender,e) =>
{
if(flag == 0)
{
flag = 1;
MessageBox.Show("Coloring Text");
}
else
flag = 0;
};
//My TextBox handler
this.EditRichTextBox.KeyPress += (sender,e) =>
{
try
{
string tmp = Environment.CurrentDirectory + "\\" + "mydll" + ".dll"; Assembly a = Assembly.LoadFrom(tmp);
Type t = a.GetType("MyPlugIn.colorclass");
MethodInfo mi = t.GetMethod("color");
Object obj = Activator.CreateInstance(t);
Object[] Params = new Object[5];
Params[0] = EditRichTextBox.Text;
Params[1] = EditRichTextBox.Handle;
Params[2] = ErrorTextBox.Handle;
Params[3] = EditRichTextBox;
Params[4] = flag;
mi.Invoke(obj, Params);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
};
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new MainForm());
}
}
}
And this is the DLL file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace MyPlugIn
{
public class colorclass
{
public void color(string Text, Object Hndl_Text, Object Hndl_Err, RichTextBox box,int flag)
{
if (flag == 1)
{
int start = box.TextLength;
int end = box.TextLength;
//Textbox may transform chars, so (end-start) != text.Length
box.Select(start, end - start);
{
box.SelectionColor = Color.Blue;
}
box.SelectionLength = 0; // clear
}
}
}
}

Yes, your code uses Reflection. These lines are an example:
Type t = a.GetType("MyPlugIn.colorclass");
MethodInfo mi = t.GetMethod("color");
Object obj = Activator.CreateInstance(t);
Whether is the best approach or not, or whether it's necessary for this task, it's a different topic.

Related

How can I create big empty white box and write some text in the middle of it?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MyTest
{
public partial class Form1 : Form
{
private int x, y;
private int gap = 0;
private int startingY = 150;
private GroupBox lastGB = null;
public Form1()
{
InitializeComponent();
GroupBox gb = new GroupBox();
gb.Location = new Point(100, (lastGB == null ? startingY : lastGB.Bounds.Bottom));
gb.Size = new Size(1220, 400);
gb.BackColor = SystemColors.Window;
gb.Text = "";
gb.Font = new Font("Colonna MT", 12);
this.Controls.Add(gb);
}
It's creating a small line on the top of the groupbox and I don't want this line to show.
And I want to write some text on it in the middle of it.
How can I make it just complete white ? And how to write some text in the middle on the groupbox ?
The main idea is to create over the form a white sheet or box with text inside that's it.
It looks like your intention is to put subsequent boxes just below the last box. As mentioned, a Label would probably be best. I'd also move that code to a method you can call over and over to keep from repeating code elsewhere. You could pass a message to display in the Label. Also, don't forget to update the reference to the "last box" when ever you create a new one:
public partial class Form1 : Form
{
private int x, y;
private int gap = 0;
private int startingY = 150;
private Label lastLbl = null;
public Form1()
{
InitializeComponent();
AddLabel("Hello World");
}
private void button1_Click(object sender, EventArgs e)
{
AddLabel(DateTime.Now.ToString());
}
private void AddLabel(String msg)
{
Label lbl = new Label();
lbl.Location = new Point(100, (lastLbl == null ? startingY : lastLbl.Bounds.Bottom));
lbl.Size = new Size(1220, 400);
lbl.BackColor = Color.White;
lbl.Text = msg;
lbl.TextAlign = ContentAlignment.MiddleCenter;
lbl.Font = new Font("Colonna MT", 12);
this.Controls.Add(lbl);
lastLbl = lbl;
}
}

How to add dynamically created hyperlink to stack panel programmatically wpf

i am creating hyperlinks and want to add it to stack panel.
for (int i = 1; i <= links.Length; i++)
{
Hyperlink hyperlink = new Hyperlink()
{
NavigateUri = new Uri(links[i - 1])
};
}
hyperlink.RequestNavigate += new System.Windows.Navigation.RequestNavigateEventHandler(this.Hyperlink_RequestNavigate);
mainControl.Children.Add(hyperlink);
it gives me error -
cannot convert to system.windows.documents.hyperlink to system.windows.uielement.
i understand the namespace error but didn't find resolution because in uielement i dint find hyperlink.
Use LinkLabel instead of HyperLink
Samples:
using System;
using System.Drawing;
using System.Windows.Forms;
public class LinkLabelAddLink : Form {
LinkLabel lnkLA = new LinkLabel();
public LinkLabelAddLink(){
Size = new Size(300,250);
lnkLA.Parent = this;
lnkLA.Text = "StackOverflow.com";
lnkLA.Location = new Point(0,25);
lnkLA.AutoSize = true;
lnkLA.BorderStyle = BorderStyle.None;
lnkLA.Links.Add(0,7,"www.stackoverflow.com");
lnkLA.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(lnkLA_LinkClicked);
}
static void Main()
{
Application.Run(new LinkLabelAddLink());
}
private void lnkLA_LinkClicked(object sender,LinkLabelLinkClickedEventArgs e)
{
lnkLA.LinkVisited = true;
System.Diagnostics.Process.Start(e.Link.LinkData.ToString());
}
}
PS: You need atleast .NET 4.5

Horrible Flickering drawing in C#

Anyone have any suggestions on how to stop this drawing from flickering? I have tried each double buffering solution, stopped using .CreateGraphics, moved all of my functions all over the place, nothing has worked.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace Math
{
public partial class Form1 : Form
{
static Random rand = new Random();
ProblemBox[] problems = new ProblemBox[20];
#region Types
public enum Type
{
Basic, Algebric, Triginomic
}
public class Problem
{
public Type type;
public String problem, answer;
public Boolean isTrue;
public Problem(Type type, String problem, String answer, Boolean isTrue)
{
this.type = type;
this.problem = problem;
this.answer = answer;
this.isTrue = isTrue;
}
}
class ProblemBox
{
public Rectangle rect;
public Problem problem;
public ProblemBox(Problem problem)
{
rect = new Rectangle(0, 309, 244, 30);
this.problem = problem;
}
public void move()
{
rect.Y -= 1;
}
public void draw(Graphics g)
{
g.FillRectangle(Brushes.DarkGray, rect);
g.DrawString(problem.problem + "=" + problem.answer, new Font("Times New Roman", 12.0f), Brushes.DarkBlue, new PointF(rect.X + 5, rect.Y + 5));
}
}
#endregion
public Problem CreateProblem() {
char op = '+';
int a = rand.Next(20), b = rand.Next(20), c;
switch (rand.Next(4)) {
case 2:
c = a - b;
op = '-';
break;
case 3:
c = a * b;
op = '*';
break;
case 4:
c = a / b;
op = '/';
break;
default:
c = a + b;
op = '+';
break;
}
bool isTrue = rand.Next(2) == 1;
if (!isTrue) {
c += 1 + (10 - rand.Next(20));
}
return new Problem(Type.Basic, String.Concat(a + ""+op +""+ b), String.Concat(c), isTrue);
}
public Form1()
{
InitializeComponent();
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
problems[0] = new ProblemBox(CreateProblem());
}
private void panel1_Paint(object sender, PaintEventArgs e)//Tick
{
ProblemBox temp = null;
if (problems[0].rect.Y < 279)
{
temp = new ProblemBox(CreateProblem());
}
for (int i = 0; i < 20; i++)
{
if (temp != null)
{
ProblemBox temp2 = problems[i];
problems[i] = temp;
temp = temp2;
}
if (problems[i] != null)
{
problems[i].move();
problems[i].draw(e.Graphics);
}
}
Thread.Sleep(20);
DrawingPanel.Invalidate();
}
}
}
It's not a good idea to have
Thread.Sleep(20);
DrawingPanel.Invalidate();
inside Paint method. Try to avoid them and behavior may dramatically improved.
As Tigran already said, you problem is what you do not finishing repaint, which could be easily solve with something like:
(new Thread(() =>
{
Thread.Sleep(20);
this.BeginInvoke((MethodInvoker)delegate { DrawingPanel.Invalidate(); });
})).Start();
However, flickering can also occurs due to slow repainting (or rather say - not fast enough). Solution in that case if pretty simple - do not draw onto screen directly (use doublebuffering).
If you need some functionality from standard component, then you must create your own component and call it appropriately. Using Panel for something what has nothing to do for what Panel is intended for - is bad.
Here is a good starter:
[System.ComponentModel.DesignerCategory("Code")]
public class MyControl : PictureBox
{
public MyControl()
{
SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
// ...
}
}

Programmatically add toolbar and their contents in c#

I am a absolute beginner with a simple question(c# . i want to create a toolbar at runtime and their events . I am using visual studio 2008 , .net framework 3.5 , C# .
For example, in you form class you can make some like this:
ToolStrip toolStrip2 = new ToolStrip();
toolStrip2.Items.Add(new ToolStripDropDownButton());
toolStrip2.Dock = DockStyle.Bottom;
this.Controls.Add(toolStrip2);
using System;
using System.IO;
using System.Windows.Forms;
namespace DynamicToolStrip
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new DynamicToolStripForm());
}
class DynamicToolStripForm : Form
{
ToolStrip m_toolstrip = new ToolStrip();
public DynamicToolStripForm()
{
Controls.Add(m_toolstrip);
AddToolStripButtons();
}
void AddToolStripButtons()
{
const int iMAX_FILES = 5;
string[] astrFiles = Directory.GetFiles(#"C:\");
for (int i = 0; i < iMAX_FILES; i++)
{
string strFile = astrFiles[i];
ToolStripButton tsb = new ToolStripButton();
tsb.Text = Path.GetFileName(strFile);
tsb.Tag = strFile;
tsb.Click += new EventHandler(tsb_Click);
m_toolstrip.Items.Add(tsb);
}
}
void tsb_Click(object sender, EventArgs e)
{
ToolStripButton tsb = sender as ToolStripButton;
if (tsb != null && tsb.Tag != null)
MessageBox.Show(String.Format("Hello im the {0} button", tsb.Tag.ToString()));
}
}
}
}

Why aren't the buttons in my C# Application working?

I am doing this lab out of a book on my own, and I made an application in which sharks are racing. There is a radio button that should update a label on the right dynamically, as well as a button that actually starts the race. Everything used to work and then I renamed a few things, and now nothing works.
Screenshot of application:
image http://cl.ly/f08f4e22761464e0c2f3/content
Form Class:
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 project1
{
public partial class Game : Form
{
private Shark[] sharks;
private Guy[] guys;
private Guy selectedGuy;
public Game()
{
InitializeComponent();
Random moreRandom = new Random();
int start = myTrack.Location.X;
int finish = myTrack.Width - 65;
sharks = new Shark[4]
{
new Shark() {myRandom = moreRandom, myPictureBox = myShark1, myPBStart = start, trackLength = finish},
new Shark() {myRandom = moreRandom, myPictureBox = myShark2, myPBStart = start, trackLength = finish},
new Shark() {myRandom = moreRandom, myPictureBox = myShark3, myPBStart = start, trackLength = finish},
new Shark() {myRandom = moreRandom, myPictureBox = myShark4, myPBStart = start, trackLength = finish}
};
guys = new Guy[3]
{
new Guy() {myName="Joe", cash=50, myRadioButton=rbGuy1, myLabel=labelBet1},
new Guy() {myName="Bob", cash=75, myRadioButton=rbGuy2, myLabel=labelBet2},
new Guy() {myName="Al", cash=45, myRadioButton=rbGuy3, myLabel=labelBet3}
};
selectedGuy = guys[0];
rbGuy1.Tag = guys[0];
rbGuy2.Tag = guys[1];
rbGuy3.Tag = guys[2];
updateGui();
}
private void myChanged(object sender, EventArgs e)
{
selectedGuy = getSelectedGuy(sender);
betterLabel.Text = selectedGuy.myName;
}
private void betAmountValue(object sender, EventArgs e)
{
updateMin();
}
private void Bet_Click(object sender, EventArgs e)
{
int bet = (int) betAmount.Value;
int myFish = (int) sharkNumber.Value;
selectedGuy.placeBet(bet, myFish);
updateGui();
}
private void raceBtn_Click(object sender, EventArgs e)
{
betBtn.Enabled = false;
bool noWinner = true;
while(noWinner)
{
for (int dogFish = 0; dogFish < sharks.Length; dogFish++)
{
Application.DoEvents();
if(sharks[dogFish].Swim())
{
showWinner(dogFish);
collectBets(dogFish);
noWinner = false;
}
}
}
updateGui();
betBtn.Enabled = true;
}
private void showWinner(int fish)
{
MessageBox.Show(string.Format("Winner Winner People Dinner! \nShark {0} won!", fish + 1));
}
private void collectBets(int fish)
{
for (int guyNumber = 0; guyNumber < guys.Length; guyNumber++)
{
guys[guyNumber].collect(fish + 1);
guys[guyNumber].resetBet();
}
}
private void updateMin()
{
minBetLabel.Text = string.Format("Minimum bet: 5 bucks", betAmount.Value);
}
private Guy getSelectedGuy(object sender)
{
RadioButton rb = (RadioButton)sender;
return (Guy)rb.Tag;
}
private void updateGui()
{
for (int guyNumber = 0; guyNumber < guys.Length; guyNumber++)
{
guys[guyNumber].updateLabels();
}
for (int fish = 0; fish < sharks.Length; fish++)
{
sharks[fish].startPosition();
}
updateMin();
}
}
}
Shark Class:
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
namespace project1
{
public class Shark
{
public int myPBStart; // Where the PictureBox starts
public int trackLength; // How long the racetrack is
public PictureBox myPictureBox = null; // The PictureBox object
public int location = 0; // My location on the racetrack
public Random myRandom; // An instance of Random
public Shark()
{
location = 0;
myPictureBox = new PictureBox();
myRandom = new Random();
trackLength = 100;
myPBStart = 0;
}
public bool Swim()
{
int distance = myRandom.Next(1, 4);
location += distance;
movePB(distance);
return location > trackLength;
}
private void movePB(int distance)
{
Point p = myPictureBox.Location;
p.X += distance;
myPictureBox.Location = p;
}
public void startPosition()
{
location = myPBStart;
Point p = myPictureBox.Location;
p.X = location;
myPictureBox.Location = p;
}
}
}
I can supply more resources if needed, but this is the main gist of it.
Using Visual Studio, make sure of the following:
1) For each radio button, verify the CheckedChanged event is hooked up to your myChanged function.
2) Verify the "Bets" Button.Click event is hooked up to your Bet_Click function.
3) Verify the "Race!" Button.Click event is hooked up to your raceBtn_Click function.
A safe way to rename things is to right click on the variable name, Refactor, Rename. This will ensure any references to the variable are renamed properly
when you renamed them you probably did it by editing the code rather than by changing the control properties.
THe Winforms designer in VS created code for you behind the scenes that wires the invents up. This codes uses the control names. Look for a file called formname_designer.cs. Notice that there are lines that still have the old control names. You can change this code
This is why its a good habit to give controls nice names when you start.
Make sure that the events on your controls are still connected to the correct event handlers in your code. Sometimes when you rename things, this link can get broken.

Categories