Noobish Does Not Exist in the current context - c#

Why i cannot call this one? ;(
public void StartNewGame()
{
Button GamePanelHideButton = new Button();
}
public void GamePanelHideButtonClick()
{
GamePanelHideButton.Visible = !GamePanelHideButton.visible;
}
GamePanelHideButton does not exist in context :( although its created before.

Your creation of the button is scoped within startnewgame() and is not accessible to method GamePanelHideButtonClick
Move the GamePanelHideButton variable outside of both methods.
Try this
public Button GamePanelHideButton;
public void StartNewGame()
{
GamePanelHideButton = new Button();
}
public void GamePanelHideButtonClick()
{
GamePanelHideButton.Visible = !GamePanelHideButton.visible;
}

GamePanelHideButton is a local variable - it only "exists" while the StartNewGame method is actually executing, and the only place you can actually refer to it is from inside the StartNewGame method. You should make this a field (class-wide variable).
Also, your statement that "it's created before" it's used is decidedly not true (or, at least, not necessarily true). There's nothing that'll guarantee that the two methods you show will be executed in any particular order - you could execute them in any order you feel like for all the compiler knows.

Moved this Button GamePanelHideButton = new Button(); outside any method and it worked, thank u all serious people for help.
Button GamePanelHideButton = new Button();

Related

C# - dll event handler

I am setting a .dll file to create a new form and a new button, but i want that button to do something. Is it possible to create a event handler in a dll file?
public static byte sbuton( string er, int by,int re)
{
Form fg = new Form();
fg.Show();
Button b1 = new Button();
fg.Controls.Add(b1);
b1.Text = er;
b1.Location = new Point(by, re);
return 0;
}
This is the code that creates a form with a button in it.
When I try to create a new event handler, as I would in a form, I get this error: "An object reference is required for the non-static field, method or property".
public static byte sbuton( string er, int by,int re)
{
Form fg = new Form();
fg.Show();
Button b1 = new Button();
fg.Controls.Add(b1);
b1.Text = er;
b1.Location = new Point(by, re);
b1.Click += new EventHandler(b1_click);
}
private void b1_click(object sender , EventArgs e)
{
}
This is the code from the form where I want use the dll
private void button1_Click(object sender, EventArgs e)
{
if (richTextBox1.Text.Contains("add") && richTextBox1.Text.Contains("buton") && richTextBox1.Text.Contains("text"))
{
form.sbuton("buton", 10, 10);
}
}
This creates a button, but nothing happens when the button is clicked, because no event handler is assigned to it in the .dll file.
And also,sorry for the bad english,it is not my native language.
What can i do?
Thanks!
It's not clear from your question what the context is. Without a good, minimal, complete code example it's difficult to provide a really good answer.
But in your example, it appears that your event handler is in the same DLL (and I assume, the same class) as the sbuton() method. If that's the case, then all you need to do in order to use the event handler is make it a static method:
private static void b1_click(object sender , EventArgs e)
{
}
Now, since you didn't post any of the code in the method, never mind the full context, it's not certain that would work. I.e. if there is a good reason for that method being a non-static method, then you will have to subscribe the event handler by referring to the method with a reference to an actual instance of the containing class. If that's the case, then the question commenter Daniel Kelley suggests, An object reference is required for the non-static field, method, or property?, may turn out to be appropriate for your needs after all.
Finally, note that none of this has anything to do with the code being in a DLL. You would have run into this same problem had your sbuton() method been in the same project from which you're calling it.

Adding buttons by a function

I want to add a button, using a function that takes all the arguments in one line, to keep it clean. But if I try to add the button via This.Controls.Add, I get an error because the function is static. What should I write instead of This (something like Form1.Controls.Add) so I can do everything in one function?
You could take the form as an argument to the static function:
public static void CreateButton(Form targetForm, param1, param2, ...) {
Button b = new Button();
...
targetForm.Controls.Add(b);
}
...but unless this method is going to be used to add buttons to a variety of forms, I don't see the advantage of making it static like this. It seems like a sort of OO anti-pattern. I would probably make it non-static and use this.
I would just have your function return the button:
//Usage
this.Controls.Add(CreateButton(...));
//Function def
public static Button CreateButton(...)
{
Button createdButton = new Button();
...
return createdButton;
}
Assignment returns the result of the assignment (so you can chain them). So to inline the assignment:
//With a variable (I did *not* say it was good practice to do this)
this.Controls.Add(myVar = CreateButton(...));

c# objects modification: a strange behaviour

I'm developing a WPF C# application and I have a strange behaviour in modification of objects. I try to explain it in general way.
Suppose that you have an object of a class described as follows:
public class A
{
int one;
bool two;
List<B> listofBObjects;
}
where B is:
public class B
{
int three;
int four;
}
I pass an instance of A class and an instance of B class from a window to another, only defining two variables of type A and B in the second window and passing them before the Show() method, with the following code, executed into an instance of window FirstWindow:
SecondWindow newWindow = new SecondWindow();
newWindow.instanceOfA = this.instanceOfA; //instanceOfA is of type A
newWindow.instanceOfB = this.instanceOfA.listOfBObjects[0]; //instanceOfB is of type B
newWindow.Show();
If I have to repeat this code twice(that is, opening twice the window), in the first execution everything works as expected, infact if I modify values in instanceOfB variable, I see the modification also in instanceOfA variable. But, in the second execution, the modification in instanceOfB does not affect instanceOfA...
The modifications are done in newWindow. For example:
this.instanceOfB.three++;
this.instanceOfB.four--;
Imagine that you are in the FirstWindow. Click on a button and SecondWindow opens, passing both variables as described above. In SecondWindow, do some modifications, click on OK and SecondWindow closes, returning control to FirstWindow. If I reclick on the same button, I reopen SecondWindow. If I do modifications now, they do not affect both variables.
I try to have a look (in VS2012) at both variables in the console with control expression and I see that, in the first pass of code, both variables changes when code above is executed but, in the second pass of code, only instanceOfB changes...
EDIT:
Following the code that I use to pass parameters to SecondWindow...types are explaind below
IntermediatePosition obj = ((FrameworkElement)sender).DataContext as IntermediatePosition; //IntermediatePosition is Class B
IntermediatePositionsSettingsWindow ips = new IntermediatePositionsSettingsWindow();
ips.currentIntermediatePosition = obj;//this is the instanceOfB
ips.idxOfIpToModify = obj.index;
ips.currentSingleProperty = this.currentPropertyToShow; //this is the instanceOfA object
ips.sideIndex = this.sideIndex;
ips.ShowDialog();
Consider that obj is given by a button selection into a datagrid, in which each row represents an IntermediatePosition object. In the datagrid, there is a column button and, clicking by buttons, IntermediatePositionsSettingsWindow is opened with the proper data
EDIT:
I've performed the folloqing check:
this.currentPropertyToShow.sides[this.sideIndex].intermediatePositionList[i].Ge‌​tHashCode() == obj.GetHashCode()
where i is the index of related IntermediatePosition object. At first usage of IntermediatePositionsSettingsWindow the objects result equals, but in second usage they are different
Why this thing happens?
If it is needed any other clarification, I will edit the question
Thanks
It's difficult to give a proper answer to this, as there is insufficient code to correctly work out the issue. However, if you are databinding, then I believe you need to implement this interface. It is possible that you're issue is simply that you're model is not reflecting the changes to the screen.
I can't reproduce your problem. Here's a simplified representation of your class relation (as I understood from your question). Please let us know if this is correct:
public partial class MainWindow : Window
{
internal A instanceOfA;
internal B instanceOfB;
public MainWindow()
{
InitializeComponent();
instanceOfB = new B() { };
instanceOfA = new A() { listOfBObjects = new List<B>() { instanceOfB } };
}
private void Button_Click(object sender, RoutedEventArgs e)
{
SecondWindow newWindow = new SecondWindow();
newWindow.instanceOfA = this.instanceOfA; //instanceOfA is of type A
newWindow.instanceOfB = this.instanceOfA.listOfBObjects[0]; //instanceOfB is of type B
newWindow.Show();
}
}
public partial class SecondWindow : Window
{
internal A instanceOfA;
internal B instanceOfB;
public SecondWindow()
{
InitializeComponent();
Loaded += SecondWindow_Loaded;
}
void SecondWindow_Loaded(object sender, RoutedEventArgs e)
{
MessageBox
.Show(String.Format("{0}",
this.instanceOfB == this.instanceOfA.listOfBObjects[0]));
this.instanceOfB.three++;
this.instanceOfB.four--;
}
}
Note: this is not an answer, just trying to establish some common ground for further discussions, as comments don't leave you enough freedom for code samples.
Thanks to #pm_2 and #BillZhang comments, I found a row in my code in which this.currentPropertyToShowwas edited. After the returning back at first window, infact, I perform the refresh of the window, but it is not needed to edit this.currentPropertyToShow, so I have commented it and everything works!
Thanks everybody for precious comments and suggestions!

Initializing events with initializer syntax

I often want to write something like this:
new Form
{
Text = "Caption",
Controls =
{
new Button { Text = "Button 1", Click = (s, e) => MessageBox.Show("Button 1 Clicked"), Location = new Point(10, 10) },
new Button { Text = "Button 2", Click = new EventHandler(Button2Clicked), Location = new Point(10, 40) },
new Button { Text = "Button 3", Click = Button3Clicked, Location = new Point(10, 70) },
},
}
Initializer syntax is just sugar, so why can't the compiler figure out how to generate code for an event subscription?
Gimme some sugar, baby!
When initializer syntax was invented, someone must have thought about events and rejected them. I've been trying to imagine what the rationale might have been and am coming up blank.
Is it because an event is a multi-cast object that might have more than one subscriber? No, this is an initialization process; There can be no other subscribers. [Updated] Not true, initializers are applied post-construction and an object can subscribe to its own events.
A note to Eric: I've heard the Why doesn't C# implement feature X speech. In this case, someone was already there, implementing initializers.
Updated
There seems to be contention/confusion because I used Click = in my example. The actual syntax is not relevant to the question. It could just as easily be Click += which mirrors the way you have to add a handler normally. I prefer the former because it's consistant with the rest of the initializer syntax, but ultimately I don't care, just so long as I can subscribe to an event in an initializer list.
Another Update
I do realize that adding the feature now is probably unlikely. The first issue that comes to mind is that Intellisense has to be updated. There are probably many other things that would hinder adding this feature now. My question is: Why didn't they add it in the first place. There must have been something compelling that warrented the 'nay' vote.
I cannot see any reason why they could not have provided this small teaspoon of sugar, I guess they just didn't!
There is already quite a lot of syntactic sugar involved in events, if simply declare an event on a class without providing your own implementation, the compiler is providing a delegate backing field for you, plus add / remove 'method' implementations. ALso, when you add an event handler, the compiler uses delegate inference, allowing you to simply point to a method, rather than create a delegate that represents the method.
Interestingly, Mono C# does allow you to add an event handler in an object initializer:
http://tirania.org/blog/archive/2009/Jul-27-1.html
Time to switch to Mono ;-)
Try simply assigning an event:
Click = (o,e) => { <CODE> }
Doesn't work. Initializers work only with things you can directly assign like that. This is because events need to be able to notify anyone they want (you shouldn't be allowed to remove someone else's registration for that event on accident).
I'm not sure if this is their reasoning, but it works for me.
There's a big difference between fields and events. There's an excellent article here outlining the differences, but that's the answer to your question: A field can be assigned a value; an event looks like a field but is a very different beast.
Edit
From the article I linked to:
We have seen that the event keyword is a modifier for a delegate declaration that allows it to be included in an interface, constrains its invocation from within the class that declares it, provides it with a pair of customizable accessors (add and remove), and forces the signature of the delegate
Remember that event is a shortcut; behind the scenes, the compiler creates an object with add() and remove() methods. Like:
public class Button {
public event EventHandler Click {
void add {...}
void remove {...}
}
}
Perhaps this will offer some insight... :
Button btn = new Button {Click += (s, e) => MessageBox.Show("hello")};
The error message you get is "Cannot initialize type 'Button' with a collection initializer because it does not implement IEnumerable"
Still another note... if you assign the event handler from within the form, you can do this:
this.button1.Click += (s, e) => this.textBox1.Text = e.ToString();
You couldn't access form variables from the code you've created. I get where you're coming from, and I don't disagree... what you're doing could be made to work. I guess my point is that there are reasons why the decision was made not to make it work.
Yep, should be part of the language!
But, here's a tricky workaround that lets you subscribe to events within an initializer list...
public class TestClass
{
public class MyButton : Button
{
public EventHandler ClickSubscriber
{
get { return null; }
set { Click += value; }
}
}
public static void RunTest()
{
new Form
{
Text = "Caption",
Controls =
{
new MyButton
{
ClickSubscriber = (s, e) =>
MessageBox.Show("Button 1 Clicked"),
},
},
};
}
}

C# Call function in a class from another class

I'll start of by saying I'm not a developer. Yes this is a c# nightmare. But this is a one time tool and thats it. Quick and Dirty it just needs to work and thats it.
I have the following code:
public string[] get_status(string local_fname)
{
var dts_doc = new HtmlAgilityPack.HtmlDocument();
dts_doc.Load(local_fname);
//Pull the values
var ViewState = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[1]/input[4]/#value[1]");
var EventValidation = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[2]/input[1]/#value[1]");
string ViewState2 = ViewState.Attributes[3].Value;
string EventValidation2 = EventValidation.Attributes[3].Value;
//Display the values
//System.Console.WriteLine(ViewState.Attributes[3].Value);
//System.Console.WriteLine(EventValidation.Attributes[3].Value);
//System.Console.ReadKey();
return new string[] { ViewState2, EventValidation2 };
}
I want to call get_status from a button on my Main.cs which will show 2 Message Boxes with ViewState2 and EventValidation2.
Again, I'm not a developer, this is probably the wrong way of doing things. But I just need a quick and dirty solution to get this job done once.
Make the function static by adding the static keyword to the function definition:
static public string[] get_status(string local_fname)
Use the class name to reference the function from your Main class.
try this:
foreach(string s in get_status(localFname))
{
MessageBox.Show(s);
}
As you said, it is quick and dirty and I stayed faithful to that paradigm.
And yes, if you need to acces another class, make the method static or just simply create an instance and call the method on it. I hope I have understood the problem correctly.
if you are using visual studio, go to the Button you want to click, double-click the button. This will create an eventhandler. In the eventhandler you should call the above method.
protected void Button1_Click(object sender, eventArgs e)
{
string local_fname = someValue;
string results[] = get_status(local_fname);
MessageBox.Show(results[0]);
MessageBox.Show(results[1]);
}

Categories

Resources