I have a quick C# question.
I have a list that I need to pass onto a method. So I did this:
Form2 f2 = new Form2(JogadoresList);
f2.novoJogo(JogadoresList);
And on another class:
public void novoJogo(List<Jogadores> JogadoresList)
{}
But now I want to call the novoJogo method from a
private void button1_Click(object sender, EventArgs e)
{
}
method. How can I call the novoJogo method if I don't have parameters to pass onto it and don't want to replace the novoJogo's list? Thank you.
You can just call novoJogo passing null value as parameter:
novoJogo(null);
Or an empty list:
novoJogo(new List<Jogadores>());
Also in the novoJogo method, you could define the List<> as an optional parameter:
public void novoJogo(List<Jogadores> JogadoresList=null)
{}
Then, you can call it without passing the argument in the the click event as I show below:
private void button1_Click(object sender, EventArgs e)
{
novoJogo();
}
Either the method needs the list, or it doesn't. So the fact you are asking this is... troubling.
However, you have a couple options. Just pass null:
private void button1_Click(object sender, EventArgs e)
{
//Hopefully you held onto that reference!
f2.novoJogo(null);
}
Or use default arguments/optional parameters:
public void novoJogo(List<Jogadores> JogadoresList = null)
{}
private void button1_Click(object sender, EventArgs e)
{
//Hopefully you held onto that reference!
f2.novoJogo();
}
In both cases, make sure that novoJogo will be OK with a null list passed to it (NRE is really easy to get here if you weren't careful). And consider if your design makes sense here, if only part of the function needs the list, should that really have been two functions instead of one?
Change the access-level of JogadoresList to public static or internal static so you can access it via button1_click.
Related
So I am a beginner in software development and practicing C# in my time at home.
I have a project that I am working on and have reached a point where I am not sure how to code the functionality.
Imagine in my solution I have a winform UI with a dropdown. Inside that dropdown the user can make a choice and click a button to run a procedure. Depending on what the user has picked, it should initialize the class/object that is picked.
So the dropdown will have options such as; runOptionOne, runOptionTwo. If runOptionTwo is picked in the dropdown, upon clicking the button it will do:
runOptionOne runoptionone = new runOptionOne();
runoptionone.Doaction();
I do not want to have string checks on the dropdown as that will be loads of if statements.
Is there a technique or method to initialize a specific class based on user choice.
Combobox.Items accepts objects. For displaying, their ToString() method will be used.
This makes it possible to access the object directly via SelectedItem. As long as they share a common interface, it's easy to call a method on them.
private void button1_Click(object sender, EventArgs e)
{
var obj = (Interface) comboBox1.SelectedItem;
obj.DoSomething();
}
The other classes:
internal interface Interface
{
void DoSomething();
}
class Class1:Interface
{
public void DoSomething() { }
public override string ToString() => "Option 1"; // TODO: make translatable via resource
}
class Class2:Interface
{
public void DoSomething() { }
public override string ToString() => "Option 2"; // TODO: make translatable via resource
}
And initialization like
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.Items.Add(new Class1());
comboBox1.Items.Add(new Class2());
}
I don't like this approach too much, since I consider the ToString() method to be rather developer oriented.
IMHO, a better approach is to have a dictionary with display strings as keys and objects as values. That way you also get rid of the if-statements and reduce cyclomatic complexity:
private readonly IDictionary<string, Interface> _displayItems = new Dictionary<string, Interface>
{
{"Option 1", new Class1()},
{"Option 2", new Class2()}
};
private void Form1_Load(object sender, EventArgs e)
{
foreach (var item in _displayItems)
{
comboBox1.Items.Add(item.Key);
}
}
private void button1_Click(object sender, EventArgs e)
{
var key = (string) comboBox1.SelectedItem;
_displayItems[key].DoSomething();
}
I need Method1 to repeat itself in the Method3. How can i do that?
Code example [edit1]:
namespace NamespaceName
{
public partial class ClassName
{
private void Method1(object sender, EventArgs e)
{
Statement1;
Statement2;
Statement3;
}
public void Method2 (object sender, MouseEventArgs e)
{
//Another bunch of statements
}
private void Method3 (object sender, EventArgs e)
{
"Want to repeat those statements from Method1 without copying them here"
}
}
}
P.S. I'm new to programming and i have no idea what my options are and searching the web didn't helped much either.
Sorry if this question has already been asked and if so, could you please link it here?
Edit1: Well, in attempt to write an abstract example instead of my actual code i omitted the important things. Now it should look more adequate.
Tell me if it is not what you are looking for.
You need only call your method Method1 in your Method3.
private Method3
{
//"Want to repeat those statements from Method1 without copying them here"
//For your sender parameter, assuming that was a button named btn1.
//you can send the btn1 as sender and null as eventargs.
Method1(btn1, null); //Will execute the code in your method1.
}
I have this method:
public static void InsertPageNumbering(object sender, CreateAreaEventArgs e, BaseOracleUtils OraCon)
{
PCK.SetData(OraCon);
}
How to assign it to event:
compositeLink.CreateMarginalFooterArea += BaseSettingsInit.InsertPageNumbering;
CreateMarginalFooterArea have this parameters:
public delegate void CreateAreaEventHandler(object sender, CreateAreaEventArgs e);
Is any option assign method (with keeping OraCon parameter)?
The compiler says it all.
CS0123 - No overload for InsertPageNumbering matches delegate CreateAreaEventHandler.
If you were able to assign the method to the event what should happen during invocation of the event? What value of BaseOracleUtils should be passed as the OraCon parameter?
Unfortunately you are not able to provide default for the last parameter either. The only solution I see is to either extend the delegate to accept one more parameter.
Or create a wrapper around your InsertPageNumbering method such as
public static void InsertPageNumberingWrapper(object sender, CreateAreaEventArgs e)
{
InsertPageNumbering(sender, e, GetBaseOracleUtils());
}
which would provide some reasonable value as the last parameter to it. And then add this wrapper to the event. GetBaseOracleUtils() could pull the value out of somewhere (I have no idea what are you trying to solve and where should the value come from).
I have an event handler on my form for a LinkLabel linkLabel2_LinkClicked:
private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
//code here
}
I need to call it from another method that does not have an object sender and any eventargs:
private void UpdateMethod()
{
linkLabel2_LinkClicked(this, ?????)
}
If it were a Button I would just call the PerformClick method. But there is no such for a LinkLabel that I could find.
What is the best practice to execute the code in the linkLabel2_LinkClicked event handler?
Update: I guess I was not clear on this. I wonder about the best practice as I have seen this approach. I can see from the answers that this is not the correct approach but to move the code to a separate method and call it directly from the other method. Please let me know if any other reasoning goes with this.
Update 2: I rewrote the code now as follows:
private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
CreatePreview();
}
private void UpdateMethod()
{
CreatePreview();
}
private void CreatePreview()
{
//code comes here
}
It works perfectly.
You can put null in event parameter :
linkLabel2_LinkClicked(this, null);
or create a new event object :
linkLabel2_LinkClicked(this, new LinkLabelLinkClickedEventArgs());
But the best way is create a separate methode and call it in every time you need it.
You could just pass null since you're not using the parameter anyway, but I'd recommend against that. It's discouraged to call an event directly, and it leads to code that's tough to read.
Just have the other method call CreatePreview().
private void UpdateMethod()
{
CreatePreview();
}
I have two methods:
private void RvListen_OPT()
private void RvListen_FUT()
On a certain event, both call:
void OnRvMessageReceived(object sender, SigRvMessageEventArgs args)
When OnRvMessageReceived is called, how can I check which of the two methods called it? I know it can be done using the object sender, but I'm not sure how to do it.
If you can edit the SigRvMessageEventArgs class you could add a field to it which you set differently in the two calls.
sender will (usually) give you the object that called the event. It may not because its up to the caller to actually set this.
That said, I"m not sure it should matter. If the call depends on who called it, maybe they need to be setup as separate events... Or, as Jackson mentioned, the args variable could be set to allow the OnRvMessageReceived event can respond to that.
Set sender to a string if you can't change SigRvMessageEventArgs to take an additional property... But the best approach would be to modify SigRvMessageEventArgs if possible.
private void RvListen_OPT()
{
OnRvMessageReceived("RvListn_OPT()", new SigRvMessageEventArgs())
}
private void RvListen_FUT()
{
OnRvMessageReceived("RvListn_FUT()", new SigRvMessageEventArgs())
}
void OnRvMessageReceived(object sender, SigRvMessageEventArgs args)
{
if(sender.ToString() == "RvListn_OPT()"){
// do work
}
else if(sender.ToString() == "RvListn_FUT()"){
// do work
}
}