So what i have is basically this:
public partial class ShowList : UserControl
{
public int count;
private static LoadMovies lm = new LoadMovies();
public List<Movie> movieList = lm.GetMovieList();
public ShowList(string genreTitel)
{
InitializeComponent();
......
......
Load(genreTitel)
}
public void Load(string genreTitel)
{
lm.ReadMoviesToList();
string picturepath = Environment.CurrentDirectory + #"\Pictures" + #"\Pictures\";
IEnumerable<Movie> genreMovieList =
movieList.Where(m => m.MovieGenres.Contains(genreTitel) && m.MovieNumberOfRatings > 80).Take(20);
Movie movie1 = genreMovieList.ElementAt(count);
label29.Text = movie1.MovieName;
pictureBox9.Image = Image.FromFile(picturepath + movie1.MovieId + ".jpg");
label24.Text = "Rating: " + Math.Round(movie1.MovieAverageRating, 2);
}
private void Btn_Click(object sender, EventArgs e)
{
count++;
//HERE I NEED SOME CODE TO RELOAD LOAD-METHOD.
}
What i have tried, is to just write Load(); but as the method needs the genreTitel. And i cant reach the genreTitel.
How do i increment count, and reload Load(genreTitel) when clicking on button?
Save genreTitel (title?) to a private variable. In the constructor assign the passed in to the new private variable, then you can access it from the Btn_Click.
Declare a string genreTitel (or name it whatever you want) under your movielist declaration and then before you call Load(genreTitel) the first time in the constructor, do:
this.genreTitel = genreTitel.
This way you have a genreTitle variable accessible to the rest of the class
Assuming you're getting genreTitel from some form field, you can access that field in your Click Event Handler.
Ergo, where you tried to put simply Load(), use Load(formField.Text).
Edit: Just noticed that ShowList(string genreTitel) was a constructor, not a method.
In that case, instantiate a private variable and assign genreTitel to it in your constructor.
do like this
//declare the class level variable like this
private string mgenretitle;
public ShowList(string genreTitel)
{
// initialize the variable over here like this
mgenretitle = genreTitel;
InitializeComponent();
......
......
Load(genreTitel)
}
and then use it over here
private void Btn_Click(object sender, EventArgs e)
{
count++;
// call your load method over here
Load(mgenretitle);
//HERE I NEED SOME CODE TO RELOAD LOAD-METHOD.
}
Related
I want to access array from one class to another class because my end-user enter the name list on one class. That list store into array in the same class. Then that name list access from another class. I'm not getting any errors in compile time. only I'm getting a run time error. I'm literally sorry to all coz I'm absolutely noob :(
public partial class custom : Form //class one which is end user enter the name list
{
public string PresentValue;
public string NormalValue;
public string[] PValue = new string[50];//public array
public string[] NValue = new string[50];//public array
}
public static int PresentArray = 0;// this line is used to increment the array index
private void cstmsvbtn_Click(object sender, EventArgs e)//this line enter the user namelist
{
PresentValue = cstmtst1.Text + "_PV";//concatinate '_PV'
NormalValue = cstmtst1.Text + "_NV";//concatinate '_NV'
PValue[PresentArray] = PresentValue;
NValue[PresentArray] = NormalValue;
PresentArray++;
}
public partial class print : Form // class to which is end user want to access that name list
{
custom customarray = new custom();// I instantiate the custom cass object
private void button1_Click(object sender, EventArgs e)//when i press this button message box show an empty white box only
{
MessageBox.Show(CustomArray.PValue[0],CustomArray.NValue[0]);
}
}
This is a common requirement and there are many ways to achieve this outcome (some of which might be considered "hacky"). Things I don't recommend:
Changing visibility to public for data fields that should be private
Creating tight dependencies of one form to the implementation details of another.
Creating "global" variables using the static keyword.
Since you claim to be a "noob" I'd like to suggest learning about the event keyword and using Events to communicate between forms. Yes, there is a small learning curve here, but chances are you'll use this a lot and it will be a good investment. I put a link in the Comments section so you can clone or browse this example and see if it does what you want it to (I recommend setting debugger break points so you can see why it does what it does).
What you have (according to your post) is a print form and a custom form. And though you don't really say, this example will have a MainForm that can show the other two:
PrintForm
The PrintForm requires the NValue and PValue arrays to do its printing. By declaring an event named ArrayRequest we give it the ability to request these arrays. Importantly, this class doesn't need to have any knowledge of where this information might be coming from.
public partial class PrintForm : Form
{
public PrintForm() => InitializeComponent();
This is how the class can initiate the request
public event ArrayRequestEventHandler ArrayRequest;
protected virtual void OnArrayRequest(ArrayRequestEventArgs e)
{
ArrayRequest?.Invoke(this, e);
}
When the button is clicked, try and get the information by callingOnArrayRequest
private void buttonShowArray_Click(object sender, EventArgs e)
{
ArrayRequestEventArgs req = new ArrayRequestEventArgs();
OnArrayRequest(req);
if(req.Count == 0)
{
MessageBox.Show("Invalid Request");
}
else
{
String[] allValues =
Enumerable.Range(0, req.Count)
.Select(index => $"{req.NValue[index]} | {req.PValue[index]}")
.ToArray();
MessageBox.Show(
text: string.Join(Environment.NewLine, allValues),
caption: "All Values"
);
}
}
}
// Defined outside the PrintForm class
public delegate void ArrayRequestEventHandler(Object sender, ArrayRequestEventArgs e);
public class ArrayRequestEventArgs : EventArgs
{
public int Count { get; set; }
public string[] PValue { get; set; }
public string[] NValue { get; set; }
}
CustomForm
The CustomForm as shown in your post is the class that contains the arrays.
public partial class CustomForm : Form
{
public CustomForm()
{
InitializeComponent();
}
We give this class the ability to fulfill a request for the arrays.
internal void ArraysRequested(object sender, ArrayRequestEventArgs e)
{
e.Count = _presentArray;
e.NValue = _nValue;
e.PValue = _pValue;
}
The data held in this class should be private.
// These should all be private
// See naming conventions: https://stackoverflow.com/a/17937309/5438626
// Set up visual studio to do this automatically: https://ardalis.com/configure-visual-studio-to-name-private-fields-with-underscore/
private string _normalValue;
private string _presentValue;
private int _presentArray = 0;
private string[] _pValue = new string[50];//public array
private string[] _nValue = new string[50];//public array
private void cstmsvbtn_Click(object sender, EventArgs e)
{
_presentValue = $"{cstmtst1.Text}_PV"; //concatinate '_PV'
_normalValue = $"{cstmtst1.Text}_NV"; //concatinate '_NV'
// Make sure index doesn't exceed the size of the array
if ((_presentArray < _pValue.Length) && (_presentArray < _nValue.Length))
{
_pValue[_presentArray] = _presentValue;
_nValue[_presentArray] = _normalValue;
_presentArray++;
}
else MessageBox.Show("Array is Full");
Text = $"Custom: Count={_presentArray}";
cstmtst1.Text = $"Hello {_presentArray + 1}";
}
}
MainForm
It is the MainForm class that oversees the operations and "knows" how the forms should interact. The constuctor method is where the connection is made between the event fired by PrintForm and the fulfillment by the CustomForm.
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
// THIS IS THE "GLUE"
_printForm.ArrayRequest += _customForm.ArraysRequested;
}
private CustomForm _customForm = new CustomForm();
private PrintForm _printForm = new PrintForm();
// In MainForm.Designer.cs
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
_customForm.Dispose();
_printForm.Dispose();
}
base.Dispose(disposing);
}
private void buttonShowCustom_Click(object sender, EventArgs e)
{
_customForm.ShowDialog(owner: this);
}
private void buttonShowPrint_Click(object sender, EventArgs e)
{
_printForm.ShowDialog(owner: this);
}
}
You will need to adapt this to your specific requirements but hopefully this will give you some basics to go on.
I am trying to fill DataGridView. However, since I am doing it on FileSystemWatcher handler, which is static class, it gives me error:
An object reference is required for non-static field, method, or property
If I change class to non-static then EventHandler gives same error. I am currently in loop and couldnt find solution. Could you please help me to solve this issue?
class FCheck
{
public static void tpCard_Created(object sender, FileSystemEventArgs e)
{
Console.WriteLine("ThreadId:" + Thread.CurrentThread.ManagedThreadId + " " + "File:" + e.FullPath);
if (Path.GetExtension(e.FullPath) == ".f")
{
// Do something....
Form1.populateTable(tp);
}
}
}
Here is Main Form1:
public void checkTPFiles()
{
FileSystemWatcher fw = new FileSystemWatcher(#"F:\tmp");
fw.Created += LSCheck.tpCard_Created;
fw.EnableRaisingEvents = true;
}
public static void populateTable(TpCard tpCard)
{
DataGridViewRow row = (DataGridViewRow)dataGridView1.Rows[0].Clone();
row.Cells[1].Value = tpCard.FNumber;
dataGridView1.Rows.Add(row);
}
One simple solution is to pass a Form1 instance to your FCheck class.
In your Form1:
public void checkTPFiles()
{
FileSystemWatcher fw = new FileSystemWatcher(#"F:\tmp");
var fCheck = new FCheck(this); // <= passes Form1 instance
fw.Created += fCheck.tpCard_Created; // <= no static call anymore
fw.EnableRaisingEvents = true;
}
public void populateTable(TpCard tpCard)
{
}
In your class FCheck:
class FCheck
{
private readonly Form1 _form;
public FCheck(Form1 form)
{
_form = form; // <= remember Form1 instance for future use
}
public void tpCard_Created(object sender, FileSystemEventArgs e)
{
Console.WriteLine("ThreadId:" + Thread.CurrentThread.ManagedThreadId + " " + "File:" + e.FullPath);
if (Path.GetExtension(e.FullPath) == ".f")
{
// Do something....
_form.populateTable(tp); // <= now it is possible to call instance methods
}
}
}
This is not the finest solution of all, because the classes are tightly coupled.
Using events and delegates so that FCheck raises an event and Form1 is reacting to it, would be a better approach. The above solution is meant to be a first step to get you running.
public class variables {
public static int edit{ get;set; }
}
And also tried:
public static int edit = 0;
public static int edit { get; set; }
public static int edits { get { return edit; } }
Using the form
form:form1 {
// Changing the value of variable to 1
private void Form1_Load(object sender, EventArgs e) {
variables.edit=1;
}
// Calling the new form where I'll use its value
private void Button_Click(object sender, EventArgs e){
form2 A=new form2();
A.Show();
}
}
form:form2{
// Showing the value of the variable in a message box
private void Form2_Load(object sender, EventArgs e){
MessageBox.show(variables.edit.ToSting());
}
}
The Message in all cases returned 0 least that call again. I need to know how to make the values initialize step as the first. I have to tab Use the many variable that keep data from one form to another and use in the load.
Make sure your class variables is static, not only the fields/properties:
public static class variables {
public static int edit = 0;
}
Another source of problem with static classes is when you use one field/property when setting another:
public static class variables {
public static int someValue = 2;
public static int other = someValue + 3;
}
AFAIK, you can't be sure of what field/property will be set first by the static constructor at runtime, unless you set the values in the static constructor, like this:
public static class variables {
static variables() {
someValue = 0;
other = someValue + 3;
}
public static int someValue;
public static int other;
}
If you are declaring static fields/properties in a really non-static class, check for the problem above, and if nothing else is changing the static field/property in another place, even inside the non-static class.
In a new form top i did:
public static string AuthenticationApplicationDirectory;
public static string AuthenticationFileName = "Authentication.txt";
Then in the new form constructor i did:
AuthenticationApplicationDirectory = Path.GetDirectoryName(Application.LocalUserAppDataPath) + "Authentication";
if (!Directory.Exists(AuthenticationApplicationDirectory))
{
Directory.CreateDirectory(AuthenticationApplicationDirectory);
}
AuthenticationFileName = Path.Combine(AuthenticationApplicationDirectory,AuthenticationFileName);
Then in form1 Load event:
private void Form1_Load(object sender, EventArgs e)
{
Authentication.AuthenticationFileName = Path.Combine(Authentication.
AuthenticationApplicationDirectory, Authentication.AuthenticationFileName);
if (File.Exists(Authentication.AuthenticationFileName) &&
new FileInfo(Authentication.AuthenticationFileName).Length != 0)
{
string[] lines = File.ReadAllLines(Authentication.AuthenticationFileName);
}
else
{
Authentication auth = new Authentication();
auth.Show(this);
}
}
But getting exception in form1 load event that AuthenticationApplicationDirectory is null.
What i want to do is once if the file not exist or empty make instance and show the new form.
If the file exist and not empty then read the lines from it into string[] lines.
The problem is not How can I check if file exist and not empty then to read all lines from the file? in fact it is Why my static member is null while I have initialized it?
It seems you have put the code that initializes your static members in the Authentication class constructor, so before you initialize an instance of Authentication form, that code will not run and AuthenticationApplicationDirectory is null.
You should put your codes in static constructor of that class:
public class Authentication : Form
{
public static string AuthenticationApplicationDirectory;
public static string AuthenticationFileName = "Authentication.txt";
static Authentication()
{
AuthenticationApplicationDirectory = Path.GetDirectoryName(Application.LocalUserAppDataPath) + "Authentication";
if (!Directory.Exists(AuthenticationApplicationDirectory))
{
Directory.CreateDirectory(AuthenticationApplicationDirectory);
}
AuthenticationFileName = Path.Combine(AuthenticationApplicationDirectory, AuthenticationFileName);
}
public Authentication()
{
InitializeComponent();
}
}
I have this code:
private void timer1_Tick(object sender, EventArgs e)
{
#region BaseAddress
Process[] test = Process.GetProcessesByName(process); //Get process handle
if (test.Any())
{
int Base = test[0].MainModule.BaseAddress.ToInt32();
}
#endregion
//lots of other code blocks
}
I now want to take the region 'BaseAddress' out of the timer1_Tick control to make the code more efficient and have it run once at the beginning of the program. The other code in this control makes frequent use of the variable 'Base', what is the best way to make this globally accessible without having to go back through all the instances that use Base and do something like MyGlobals.Base, for example?
Lazy load the address into a static variable. It won't initialize until you use it for the first time, then will remain in memory for the life of the application.
public static MyGlobals
{
private static readonly Lazy<int> _processBase = new Lazy<int>(() => GetProcessBase("MyProcessName"));
// I don't recommend using the word Base, but OK...
public static int Base { get { return _processBase.Value; } }
private static int GetProcessBase(string processName)
{
int b = 0;
Process[] p = Process.GetProcessesByName(processName);
if(p != null && p.Length > 0)
{
b = p[0].MainModule.BaseAddress.ToInt32();
}
return b;
}
}
In some other part of the app...
private void timer1_Tick(object sender, EventArgs e)
{
if(MyGlobals.Base > 0)
{
// TODO: change "Base" to "MyGlobals.Base" in code below or it won't compile...
//lots of other code blocks
}
}
The method I would use in this case would be to create a singleton class ProcessFetcher (for example) with a Base property.
My class would have a fetch() function and isDataPresent property.
You can decide to call fetch manually or put it on the constructor.