What will be displayed by the MessageBox? - c#

I Have Code for EventHandler like this below.
I do not know what is meant by e.Value, can someone explain and show approximately what will be displayed by the MessageBox?
void ConnectionManager_Error(object sender, EventArgs<string> e)
{
BeginInvoke((MethodInvoker)delegate()
{
State = ConnectState.NotFound;
MessageBox.Show(e.Value);
});
}
Note:
I have this code that I thought would trigger ConnectionManager Error EventHandler.
private void LogError(string error)
{
if (Error != null)
Error(this, new EventArgs<string>(error));
}
I also have this code that gives an error message containing the string to LogError method.
int lasterror = Marshal.GetLastWin32Error();
if (lasterror != 0)
LogError("Bluetooth API returned: " + lasterror.ToString());
or
if (BluetoothSetServiceState(IntPtr.Zero, ref device, ref HumanInterfaceDeviceServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE) != 0)
LogError("Failed to connect to wiimote controller");
Another Hint
To be more specific, I also already have the code below:
public event EventHandler<EventArgs<string>> Error;
and
ConnectionManager.Error += new EventHandler<EventArgs<string>>(ConnectionManager_Error);
And also this class:
public class EventArgs<T> : EventArgs
{
public T Value
{
get;
set;
}
public EventArgs(T value)
: base()
{
Value = value;
}
}
But MessageBox never appears even when the device is not connected to the computer.
I think that comes MassageBox supposed that show error messages.
Can someone show me what is wrong?

Your ConnectionManager has Error event, which passes instance of EventArgs<string> to event handlers. I believe generic event argument looks like:
public class EventArgs<T> : EventArgs
{
public EventArgs(T value)
{
Value = value;
}
public T Value { get; private set; }
}
So, ConnectionManager sets some string value to this argument of event and passes it to ConnectionManager_Error event handler. You should see value which was passed. From event name I can assume it should be error message.
NOTE: ConnectState enum, State property of ConnectionManager and its StateChanged event is not related to code you work with.

A Message Box is shown with the value provided by the EventArgs. I can only assume that your EventArgs class is a generic EventArgs implementation where the type parameters defines the type of the value.
So whatever the value is, that is what you will see in the MessageBox.

Related

C# "System.StackOverflowException:" when assigning event handler

I have an initialization routine called from the Form's Show event.
When the initialization is done, it fires an Initialized event.
In this event I assign the event handlers to the initialized objects. But as soon I try to assign this event, I get "System.StackOverflowException:". I have put a break point in the event to see if it was called recursively, but it isn't.
SCD.OCV.OnCard += OCV_OnCard;
The event handler in the SCD.OCV.OnCard is defined like this in the TOCV class:
public class CardEventArgs : EventArgs
{
public CardEventArgs(TCard card, ECardStatus status)
{
Card = card;
Status = status;
}
public ECardStatus Status { get; }
public TCard Card { get; }
}
public event CardHandler OnCard;
public delegate void CardHandler(object sender, CardEventArgs e);
protected virtual void FireCard(CardEventArgs e)
{
OnCard?.Invoke(this, e);
}
The event handler I try to assign is defined like this:
private void OCV_OnCard(object sender, TOCV.CardEventArgs e)
{
BeginInvoke((Action)delegate
{
});
}
And now to the assignment where all crash:
SCD.OCV.OnCard += OCV_OnCard; // Here I get the StackOverflowException
C# is not my major programming language (I'm more familiar with C/C++) so I'm not 100% sure if all is done correctly.
[EDIT]
Managed to track down the issue. It was a third party C/C++ DLL not terminating a string correctly. Hence a char* went wild in the memory.

Checking if parameter has been passed in windows universal c# code

Am passing a parameter as a way to allow a user to go back and make changes
private void go_back_btn_Click(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(TruckRegistrationPage), this.truckdetails);
}
Now on the trruck registration page
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
this.changeddetails= (TruckRegistrationDetails)e.Parameter;
//set the form fields based on the details
if (e.Parameter) //this throws an error of boolean not casted
{
truck_reg_no.Text = changeddetails.reg_no;
transporter_name.Text = truckdetails.owner_id;
.......assign other xaml controls
}
}
The parameters am passing are of type TruckRegistrationDetails whic is a class containing properties as below
class TruckRegistrationDetails
{
public int id { get; set; }
public string reg_no { get; set; }
public int truck_category { get; set; }
.......others
}
How do i check to see if any parameters have been passed and hence assign the xaml controls value
Change your code to this
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
changeddetails = (TruckRegistrationDetails)e.Parameter;
if (changeddetails != null)
{
truck_reg_no.Text = changeddetails.reg_no;
//do what ever you want ^^
}
}
Your check was for a boolean, but e.Parameter is an object. Here is the link to MSDN https://msdn.microsoft.com/de-de/library/windows/apps/windows.ui.xaml.navigation.navigationeventargs.parameter.aspx
I was getting an error using this approach as at some point OnNavigatedTo is called with a NavigationEventArgs.Parameter of an empty string. This was causing a Cast exception when the object is cast to the object type I passed.
I used:
if (args.Parameter is DeviceInformation)
{
DeviceInformation deviceInfo = (DeviceInformation)args.Parameter;
//Do something with object
}
This checks the type of object first to see if it matches the expected first, then the cast will not throw an exception.

Passing Value on Property Change

I have 2 forms: Form A and Form B. I also have a property field class.
Form A contains the label I want changed when a property is changed. Form B contains code that will change the property field.
Property Class Code:
public class Controller
{
private static string _customerID;
public static string customerID
{
get { return _customerID; }
set
{
_customerID = value;
if (_customerID != "")
{
FormA.ChangeMe();
}
}
}
}
Form B Code:
private void something_Click(object sender, SomethingEventArgs e) {
Controller.customerID = "Cool";
}
Form A Code:
public static void ChangeMe()
{
var frmA = new FormA();
MessageBox.Show("Test: " + Controller.customerID); //This works! Shows Cool
frmA.lb2Change.Text = Controller.customerID; //This kind of works..
MessageBox.Show("Test2: " + frmA.lb2Change.Text); //This shows the correct value. Shows Cool
}
The property field value is passed (which I know from the MessageBox) however it does not update the value on the form label itself. Why is this? What am I doing wrong? I also believe there is a better alternative for achieving what ChangeMe() method is intended to achieve -- if so are there any suggestions?
You can do the following
To define a delegate
To Implement Property Change Notification
Delegate
public delegate void OnCustomerIDChanging(object sender,CancelEventArgs e);
public delegate void OnCustomerIDChanged(object sender,object value);
public class Controller
{
private static string _customerID;
public event OnCustomerIDChanging CustoerIDChanging;
public event OnCustomerIDChanged CustoerIDChanged;
public static string customerID
{
get { return _customerID; }
set
{
// make sure that the value has a `value` and different from `_customerID`
if(!string.IsNullOrEmpty(value) && _customerID!=value)
{
if(CustomerIDChanging!=null)
{
var state = new CancelEventArgs();
// raise the event before changing and your code might reject the changes maybe due to violation of validation rule or something else
CustomerIDChanging(this,state);
// check if the code was not cancelled by the event from the from A
if(!state.Cancel)
{
// change the value and raise the event Changed
_customerID = value;
if(CustomerIDChanged!=null)
CustomerIDChanged(this,value);
}
}
}
}
}
}
in your Form and when you are initiating the Controller Object
var controller = new Controller();
controller.CustomerIDChanging +=(sd,args) =>{
// here you can test if you want really to change the value or not
// in case you want to reject the changes you can apply
args.Cancel = true;
};
controller.CustomerIDChanged +=(sd,args) =>{
// here you implement the code **Changed already**
}
The above code will give you a great control over your code, also will make your controller code reusable and clean. Same
result you can get by implementing INotifyPropertyChanged interface
INotifyPropertyChanged
you might have a look on this article to get more information
In your static method ChangeMe you are creating a new Form every time, you want to Change the value. Instead of that you want to change the value of an existing form. Therefor your Controller needs an instance of this FormA. Try it like this:
public class Controller
{
//You can pass the form throught the constructor,
//create it in constructor, ...
private FormA frmA;
private string _customerID;
public string customerID
{
get { return _customerID; }
set
{
_customerID = value;
if (_customerID != "")
{
frmA.ChangeMe();
}
}
}
}
Now you donĀ“t need to be static in your FormA:
public void ChangeMe()
{
MessageBox.Show("Test: " + Controller.customerID);
this.lb2Change.Text = Controller.customerID;
}

CA1009: Declare event handlers correctly?

I have the following event that consumers of my class can wire up with to get internal diagnostic messages.
public event EventHandler<string> OutputRaised;
I raise the event with this function
protected virtual void OnWriteText(string e)
{
var handle = this.OutputRaised;
if (handle != null)
{
var message = string.Format("({0}) : {1}", this.Port, e);
handle(this, message);
}
}
Why am I getting CA1009 Declare event handlers correctly? All the answers I found don't seem really applicable to my scenario... Just trying to understand, I don't have a real solid grasp of events and delegates yet.
Reference on CA1009: http://msdn.microsoft.com/en-us/library/ms182133.aspx
According to 'the rules', the type-parameter of EventHandler should inherit from EventArgs:
Event handler methods take two parameters. The first is of type
System.Object and is named 'sender'. This is the object that raised
the event. The second parameter is of type System.EventArgs and is
named 'e'. This is the data that is associated with the event. For
example, if the event is raised whenever a file is opened, the event
data typically contains the name of the file.
In your case, that could be something like this:
public class StringEventArgs : EventArgs
{
public string Message {get;private set;}
public StringEventArgs (string message)
{
this.Message = message;
}
}
and your eventhandler:
public event EventHandler<StringEventArgs> OutputRaised;
When you raise the event, you should offcourse create an instance of the StringEventArgs class:
protected virtual void OnWriteText( string message )
{
var handle = this.OutputRaised;
if (handle != null)
{
var message = string.Format("({0}) : {1}", this.Port, e);
handle(this, new StringEventArgs(message));
}
}
I also would like to add, that theoretically, there's nothing wrong with your code. The compiler doesn't complain and your code will work. The EventHandler<T> delegate does not specify that the type parameter should inherit from EventArgs.
It's FxCop that signals that you're violating the 'design rules' for declaring an event.
Events in .NET should usually contain some derivative of EventArgs which yours does not so I'd guess that's the problem.
Define the event args to be published by the event:
public class StringEventArgs : EventArgs
{
public StringEventArgs(string message) { this.Message = message; }
public string Message { get; private set; }
}
Change your Event declaration and publish method:
public event EventHandler<StringEventArgs> OutputRaised;
protected virtual void OnWriteText(string e)
{
var handle = this.OutputRaised;
if (handle != null)
{
var message = string.Format("({0}) : {1}", this.Port, e);
handle(this, new StringEventArgs(message));
}
}

using delegate to send string

I'am having a very annoying problem in my code, when I try to send a string from Form B to form a. I get the error message:
Object reference not set to an instance of an object.
I'am familiar with this error and normally I know how to solve this problem, but this one is different.
I need to send a Clockname from one form to the main form, I'am trying to achieve this using the code below:
delegate void ClockClocknameReceivedEventHandler(object sender, Clock.ClocknameReceivedEventArgs e);
internal class ClocknameReceivedEventArgs : EventArgs
{
string _clockname;
public string Clockname
{
get { return _clockname; }
}
public ClocknameReceivedEventArgs(string clockname)
{
_clockname = clockname;
}
}
// An event that clients can use to be notified whenever the
// elements of the list change.
public event ClockClocknameReceivedEventHandler ClocknameReceived;
// Invoke the Changed event; called whenever list changes
protected void OnClocknameReceived(Clock.ClocknameReceivedEventArgs e)
{
ClocknameReceived(this, e);
}
And the following code gets fired when pressing a button, the form will close after that:
OnClocknameReceived(new Clock.ClocknameReceivedEventArgs(ClockName));
The error(Object reference not set to an instance of an object.) I receive occurs at
ClocknameReceived(this, e);
I'am using the exact same code, from another class to the main form to send a byte array which works fine, but this one give me that error.
Anyone any ideas?
Thanks in advance!
The delegate can be null. Invoke it only if it's not null:
protected void OnClocknameReceived(Clock.ClocknameReceivedEventArgs e)
{
ClockClocknameReceivedEventHandler handler = ClocknameReceived;
if (handler != null)
{
handler(this, e);
}
}
The delegate is null when you haven't subscribed an event handler to the event yet. Subscribe an event handler:
formB.ClocknameReceived += FormB_ClocknameReceived;
with
void FormB_ClocknameReceived(object sender, Clock.ClocknameReceivedEventArgs e)
{
MessageBox.Show(e.Clockname);
}
Your not checking whether the ClocknameReceived event has been assigned (i.e. has any subscribers). Typical event handling code generally looks like:
var handler = ClocknameReceived;
if (handler != null)
{
handler(this, e);
}
This type of approach also mitigates (to an extent) race conditions with your event handler as it could be unassigned by the time you go to trigger it.
Looking at your code you could definitely tidy this up a bit. For one, your EventArgs class could be re-written with less code:
internal class ClocknameEventArgs : EventArgs
{
public ClockNameEventArgs(string name)
{
Name = name;
}
public string Name { get; private set; }
}
Then in your form, there's no need for a delegate if you have a particular type of EventArgs, your event can be declared as:
public event EventHandler<Clock.ClocknameEventArgs> ClocknameReceived;
You then hook up to this event somewhere (maybe in the FormCreate event?):
ClocknameReceived += (sender, args) {
FormB.PassName(args.Name);
};
You have to check if the event has a delegate or not
if( ClocknameReceived != null)
ClocknameReceived(this, e);

Categories