I'm having a trouble in my code with this exception:
System.FormatException
Additional information: Input string was not in a correct format.
I have two files in my visual studio C# solution:
Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EventPubSub
{
class Program
{
static void Main(string[] args)
{
Rectangle rect = new Rectangle();
// Subscribe to the Changed event
rect.Changed += new EventHandler(Rectangle_Changed);
rect.Length = 10;
}
static void Rectangle_Changed(object sender, EventArgs e)
{
Rectangle rect = (Rectangle)sender;
Console.WriteLine("Value Changed: Length = { 0}", rect.Length);
}
}
}
file Rectangle.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EventPubSub
{
class Rectangle
{
//Declare an event named Changed of
//delegate type EventHandler
public event EventHandler Changed;
private double length = 5;
public double Length
{
get
{
return length;
}
set
{
length = value;
//Publish the Changed event
Changed(this, EventArgs.Empty);
}
}
}
}
The exception arise when I execute the line: rect.Length = 10;
there is a space between { and 0 in the handler which is leading to the exception
Please change the event handler like this, all will work fine
static void Rectangle_Changed(object sender, EventArgs e)
{
Rectangle rect = (Rectangle)sender;
Console.WriteLine(string.Format("Value Changed: Length = {0}", rect.Length));
}
I have made 2 changes here -
Added a string.Format (which is not the problem)
removed the space between { & 0. it was { 0} now I made it {0} (which is the actual problem)
Try first adding try catch to catch the error it is throwing. So you could identify and fix it. This is just to help you fix your own problem next time. :)
static void Main(string[] args)
{
Rectangle rect = new Rectangle();
string errorMessage = String.empty;
try
{
// Subscribe to the Changed event
rect.Changed += new EventHandler(Rectangle_Changed);
rect.Length = 10;
}
catch(Exception ex)
{
errorMessage = ex.Message;
}
}
Related
I have the following two programs
(1) Windows forms application
(2) ClassLibrary1.dll
In the winform, the dll is loaded using appdomain. The winform subscribes to the action('TestAction') in the dll. I am trying to access the value returned by the dll action and use it in the event handler('HandleAction'). To do this I created a child class that inherits EventArgs. I changed the input arguments of the event handler(HandleAction) accordingly. But I am seeing a compiler error at Loader.Call( "RaiseAct", HandleAction, DateTime.Now.ToShortDateString()); . The error is:Cannot convert from method group to System.EventHandler
I have referred to other duplicates to this question, but they are not the same case. Any help will be very much appreciated. Thank you.
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;
using System.Reflection;
using System.Diagnostics;
using ClassLibrary1;
namespace WindowsFormsApplication2
{
[Serializable]
public class IntEventArgs : EventArgs
{
public int data;
}
[Serializable]
public partial class Form1 : Form
{
void HandleEvent(object sender, EventArgs e)
{
Debug.WriteLine("HandleEvent called");
}
void HandleAction(object sender, IntEventArgs e)
{
Debug.WriteLine("HandleAction called");
Debug.WriteLine("the value of index is " + e.data);
}
public Form1()
{
InitializeComponent();
Loader.Call( "RaiseEvent", HandleEvent, DateTime.Now.ToShortDateString());
Loader.Call( "RaiseAct", HandleAction, DateTime.Now.ToShortDateString()); // Cannot convert from method group to System.EventHandler
}
private void button1_Click(object sender, EventArgs e)
{
Application.Restart();
Application.Run(new Form1());
this.Close();
}
}
public class Loader : MarshalByRefObject
{
static string dll = #"..\ConsoleApplication1\ClassLibrary1\bin\Debug\ClassLibrary1.dll";
static AppDomain ad = AppDomain.CreateDomain("Test");
static Assembly a = Assembly.LoadFile(dll);
static object o = a.CreateInstance("ClassLibrary1.Class1");
static Type t = o.GetType();
object CallInternal1( string method, EventHandler handler, object[] parameters)
{
// Subscribe to the event
EventInfo eventInfo1 = t.GetEvent("TestEvent");
eventInfo1.AddEventHandler(o, handler);
MethodInfo m = t.GetMethod(method);
return m.Invoke(o, parameters);
}
object CallInternal2( string method, EventHandler handler, object[] parameters)
{
// Subscribe to the event
EventInfo eventInfo2 = t.GetEvent("TestAction");
eventInfo2.AddEventHandler(o, new Action<int>((index) => handler(null, new IntEventArgs { data = index })));
MethodInfo m = t.GetMethod(method);
return m.Invoke(o, parameters);
}
public static object Call( string method, EventHandler handler, params object[] parameters)
{
Loader ld = (Loader)ad.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(Loader).FullName);
object result = 0;
switch (method)
{
case "RaiseEvent":
{
result = ld.CallInternal1( method, handler, parameters);
break;
}
case "RaiseAct":
{
result = ld.CallInternal2( method, handler, parameters);
break;
}
}
return result;
}
}
}
This ClassLibrary1.dll code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ClassLibrary1
{
[Serializable]
public class Class1
{
public event EventHandler TestEvent;
public int RaiseEvent(string msg)
{
try
{
TestEvent(this, EventArgs.Empty);
}
catch (Exception ex)
{
Console.WriteLine("the exception is: " + ex.ToString());
if (ex.InnerException != null)
{
Console.WriteLine("the inner exception is: " + ex.InnerException.Message.ToString());
}
}
return 2;
}
public event Action<int> TestAction = Func;
public int RaiseAct(string msg)
{
TestAction(3);
return 5;
}
public static void Func(int a)
{
int g = 2;
}
}
}
How to work with richtextbox asynchronously? For example, I have a class and an event that logs some kind of calculation
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ExampleProject
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//I subscribe to an event that often sends messages
//and I want to display
var c = new Core();
c.Notify += DisplayMessage;
c.ExampleMethod();
}
private void DisplayMessage(object sender, LogEventArgs e)
{ //When a event arrives, transfer to richTextBox1
richTextBox1.AppendText("\r\n" + e.Date.ToString("dd/MM/yyyy HH:mm:ss "), Color.SlateGray);
richTextBox1.AppendText(e.Message, Color.Blue);
richTextBox1.SelectionStart = richTextBox1.Text.Length;
richTextBox1.ScrollToCaret();
}
}
class Core
{
public delegate void LogHandler(object sender, LogEventArgs e);
public event LogHandler Notify;
//
public void ExampleMethod()
{
//generate messages with a pause in a random value
var rand = new Random();
for (int i = 1; i < 10000; i++)
{ var pause = rand.Next(50, 2000);
Thread.Sleep(pause);
Notify?.Invoke(this, new LogEventArgs($"logged {i} pause in miliseconds {pause}", DateTime.Now, MessageType.Notice));
}
}
} //The class in which log messages are placed
class LogEventArgs
{
public string Message { get; }
public DateTime Date { get; }
public MessageType MessageType { get; }
public LogEventArgs(string mes, DateTime date, MessageType messageType)
{
Message = mes;
Date = date;
MessageType = messageType;
}
}
enum MessageType
{
Notice,
Warning,
Error,
}
//Extension method to set line colors in RichTextBox
public static class RichTextBoxExtensions
{
public static void AppendText(this RichTextBox box, string text, Color color)
{
box.SelectionStart = box.TextLength;
box.SelectionLength = 0;
box.SelectionColor = color;
box.AppendText(text);
box.SelectionColor = box.ForeColor;
}
}
}
Tried options with backgroundworker, task , synchronization... and got no result. I'm surprised that WinForms have been around for many years and Microsoft hasn't added asynchronous actions to them, for example AppendTextAsync(). How can I force text to be added asynchronously to a richtextbox?
Put another textbox on your form
Paste this code over ther top of everything in your 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.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ExampleProject
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
var c = new Core();
c.Notify += DisplayMessage;
await c.ExampleMethod();
}
private void DisplayMessage(object sender, LogEventArgs e)
{
richTextBox1.AppendText("\r\n" + e.Date.ToString("dd/MM/yyyy HH:mm:ss "), Color.SlateGray);
richTextBox1.AppendText(e.Message, Color.Blue);
richTextBox1.SelectionStart = richTextBox1.Text.Length;
richTextBox1.ScrollToCaret();
}
}
class Core
{
public delegate void LogHandler(object sender, LogEventArgs e);
public event LogHandler Notify;
public async Task ExampleMethod()
{
var rand = new Random();
for (int i = 1; i < 10000; i++)
{ var pause = rand.Next(50, 200);
await Task.Delay(pause);
Notify?.Invoke(this, new LogEventArgs($"logged {i} pause in miliseconds {pause}", DateTime.Now, MessageType.Notice));
}
}
}
class LogEventArgs
{
public string Message { get; }
public DateTime Date { get; }
public MessageType MessageType { get; }
public LogEventArgs(string mes, DateTime date, MessageType messageType)
{
Message = mes;
Date = date;
MessageType = messageType;
}
}
enum MessageType
{
Notice,
Warning,
Error,
}
public static class RichTextBoxExtensions
{
public static void AppendText(this RichTextBox box, string text, Color color)
{
box.SelectionStart = box.TextLength;
box.SelectionLength = 0;
box.SelectionColor = color;
box.AppendText(text);
box.SelectionColor = box.ForeColor;
}
}
}
Run it, click the button, then carry on typing in the other textbox - it stays responsive etc.. I don't know how long you'll have to wait to see major slowdowns as the text in the RTB gets huge.. but really you should look at periodically clipping your log so you arent building up megabytes of text in the RTB
Async in winforms is not about getting the controls to update using some async fashion; control must only be accessed by the thread that created them so any interaction with a control we generally ask that thread to do it (but I suppose it's a matter of perspective: if a background thread is asking the UI thread to update a control then it's being done asyncronous to whatever work the background thread is doing) - make sure the access you do with them is quick, do your heavy lifting (API calls?) using async way and then Invoke to get your UI thread to update the controls.
Just started learning Visual Studio and I'm trying to make a soundboard in Windows Forms.
ButtonMaker(); is the function I use to make a button for each soundfile in my directory so I don't have to make 70 different buttons for every sound, but when I run the program nothing shows up in the forms window. Anybody know why? I've tried calling the function in Main() and in the initial Form1 class but nothing happens in either. Forms class file here:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace MySoundBoard
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
///Tried running it here
}
private void Form1_Load(object sender, EventArgs e)
{
///Tried running it here
}
private void ButtonMaker()
{
string[] files = Soundfiles.GetFile();
foreach (var item in files)
{
string btnName = item.ToUpper();
Button btNname = new Button();
btNname.Text = item;
int x = 40;
int y = 40;
btNname.Location = new Point(x, y);
x = x + 50;
if (x>900)
{
x = 40;
y = y + 30;
}
}
}
private void button1_Click(object sender, EventArgs e)
{
}
}
}
Here is the SoundFiles class:
using System.IO;
using System;
using System.Text;
using System.Diagnostics;
using WMPLib;
namespace MySoundBoard
{
class Soundfiles {
WMPLib.WindowsMediaPlayer Player;
static public string[] GetFile() {
string txtPath = #"C:\Documents\path\to\sound effects";
string[] files =
Directory.GetFiles(txtPath, "*ProfileHandler.cs", SearchOption.TopDirectoryOnly);
return files;
}
public void PlayFile(String url)
{
Player = new WMPLib.WindowsMediaPlayer();
Player.URL = url;
Player.controls.play();
}
}
}
And the main project file(not that worked with yet):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MySoundBoard
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
///Tried running it here
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
As said, I'm very new to this language and any help would be appriciated!
You create the buttons but never add them to the form. Just add
this.Controls.Add(btNname);
The next thing is, that your buttons will not do something. You'll need to add an event handler as well.
btNname.Click += ...;
In order to know which button plays which sound, you need to find a way to have that association. A hacky approach is
btNname.Tag = item;
and then evaluate Tag later
Cannot enter text from class to textbox in form.
We set a keypress event in the MyTreeView class.
The text box cannot contain characters.
What should I do?
*set of textBox1.
*Change Modifiers for textBox1 properties from private to public
*Change keypress event from private to public
*(It didn't work well, so I keep it private now.)
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;
using System.Diagnostics;
namespace treeview
{
public partial class Form1 : System.Windows.Forms.Form
{
MyTreeView m_tree_view = new MyTreeView();
public Form1()
{
try
{
InitializeComponent();
System.Windows.Forms.TreeNode[] tree1 = new System.Windows.Forms.TreeNode[2];
m_tree_view.Location = new System.Drawing.Point(0, 0);
m_tree_view.Size = ClientSize;
m_tree_view.AllowDrop = true;
tree1[0] = new System.Windows.Forms.TreeNode("TreeNode1");
tree1[1] = new System.Windows.Forms.TreeNode("TreeNode2");
m_tree_view.Nodes.Add("Node1");
Controls.Add(m_tree_view);
}
catch
{
}
}
//This is the code I added.
private void Form1_Load(object sender, EventArgs e)
{
}
}
public class MyTreeView : System.Windows.Forms.TreeView
{
public MyTreeView()
{
try
{
//This is the code I added.
KeyPress += MyTreeView_KeyPress;
}
catch
{
}
}
//This is the code I added.
private void MyTreeView_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
Console.WriteLine("key_press_ok");
//error code↓
//textBox1.Text = "sample";
}
}
}
If you want just to click an button and then print some text i don't understand why you are making another class.
Will be good to make your code efficient and not complicated.
In the main class
private void SendText_Click(object sender, EventArgs e)
{
textBox1.Text = "hi";
}
But if you want to make it complicated and make a class you shuld return i variable and send it to the other class the you can use it.
Learn how to use Public and private first and then use them.
You shuld have a public class which send data and the private to recive and process.
add (Exception ex) to your try catch.
so do:
try
{
// your code
}
catch (Exception ex)
{
MessageBox.Show(ex, "Error in (add where the error is)");
Console.WriteLine(ex);
}
So you will get a detailed Exception Message, maybe it helps you or maybe you will post it here, so we can see what the problem is.
And because you have System.Windows.Forms in your Using Directive
using System.Windows.Forms;
so
System.Windows.Forms.TreeNode[] tree1 = new System.Windows.Forms.TreeNode[2];
is redundant and can be shortened to:
TreeNode[] tree1 = new TreeNode[2];
Here's the error:
It says the source of the exception is on Line20 of my class. Here is my class:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections.ObjectModel;
namespace WebServiceScanner
{
public partial class imageList : UserControl
{
private int XPosition = 0;
public imageList()
{
InitializeComponent();
Images.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Images_CollectionChanged);
}
public ObservableCollection<selectablePicture> Images { get; set; }
public void AddImage(selectablePicture image)
{
Images.Add(image);
}
public void RemoveImage(selectablePicture image)
{
Images.Remove(image);
}
public void MoveImageLeft(int index)
{
selectablePicture tmpImage = Images[index];
Images[index] = Images[index - 1];
Images[index - 1] = tmpImage;
}
public void MoveImageRight(int index)
{
selectablePicture tmpImage = Images[index];
Images[index] = Images[index + 1];
Images[index + 1] = tmpImage;
}
void Images_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
RedrawImages();
}
private void RedrawImages()
{
foreach (var picture in Images)
{
picture.Location = new Point(XPosition + panel1.AutoScrollPosition.X, 0);
XPosition += 130;
panel1.Controls.Add(picture);
}
}
}
}
Maybe I'm doing something dumb like setting an event handler at the constructor. Any ideas? This user control isn't really that complex, so there are few places where something could be wrong.
If you guys need more information please let me know.
Add a statement to instantiate Images.
public imageList()
{
InitializeComponent();
Images = new ObservableCollection<selectablePicture>();
Images.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Images_CollectionChanged);
}
I'm guessing it is something to do with the fact that Images isn't set to any value so the control is trying to render it for DesignView but Images is null hence the NullReferenceException. It's probably the code in the Constructor when it tries to register against the Images which will probably run before any injection code setting images.
Does < selectablePicture > have a parameterless public constructor? And are you instancing Images?