I'm stuck in declaring a variable with a trigger. This trigger is fired whenever the value of the variable changes and the trigger mechanism is supposed to alter the value of another variable.
Below code compiles fine but throws NullReferenceException (screenshot after exception).
file: Program.cs
using System;
using System.Windows.Forms;
namespace test {
class Program {
public static Active active = new Active();
public static FormMain formMain = new FormMain();
[STAThread]
static void Main() {
Application.Run(formMain);
}
}
}
file: DataStruct.cs
namespace test {
public class Active {
public string UserName {
get {
return (Program.formMain.labelUserName.Text);
}
set {
Program.formMain.labelUserName.Text = value;
}
}
}
}
file FormMain.cs
using System;
using System.Windows.Forms;
namespace test {
class FormMain : Form {
public Label labelUserName = new Label();
public FormMain() {
this.Controls.Add(labelUserName);
Program.active.UserName = "User Name";
}
}
}
It's because when you are in the FormMain constructor, the static variable Program.formMain has not been initialized yet, because you are creating the FormMain object which with you want to initialize Program.formMain.
Update labelUserName directly instead.
Related
I have the following form with a method called setIndex
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;
namespace ProjectName
{
public partial class SettingsWindow : Form
{
internal readonly static SettingsWindow Instance = new SettingsWindow { Visible = false };
public SettingsWindow()
{
InitializeComponent();
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string defaultsearch = listBox1.GetItemText(listBox1.SelectedItem);
Core.RegistryHelper.SaveSetting("Config", "ds", defaultsearch);
if (defaultsearch == "aaa") {
Core.LandingUrlOrig = Core.DomainName + "/defaulturl1.php";
} else {
Core.LandingUrlOrig = Core.DomainName + "/defaulturl2.php";
}
}
public static void setIndex(int i)
{
listBox1.SelectedIndex = i;
}
On another form called MainWindow during its initialization I call:
public MainWindow()
{
SettingsWindow.setIndex(0);
}
The error I get is:
An object reference is required for the non-static field, method, or property 'SettingsWindow.listBox1'
Initially the listbox method wasn't static and thus invisible from MainWindow. But now, listbox appears to not exist, even if the form has been instantiated. How do I solve this? I'm just learning C#.
Thank you in advance
because the function setIndex is static you need to use the Instance property:
public static void setIndex(int i)
{
Instance.listBox1.SelectedIndex = i;
}
or don't make that function static and then use instance in the mainwindow function:
public void setIndex(int i)
{
listBox1.SelectedIndex = i;
}
public MainWindow()
{
SettingsWindow.Instance.setIndex(0);
}
I have made a class, I make an instance of. In said instance I have these lines of code to show and close the splashscreen.
// Open (show)
public void ShowSplashScreen(bool autoClose = false)
{
splashscreen.Show(autoClose, true);
}
// Close (don't show)
public void CloseSplashScreen()
{
splashscreen.Close(TimeSpan.FromSeconds(0.3));
}
It shows up fine, but never closes, just stays there.
This is the documentation of splashscreen Close: https://learn.microsoft.com/en-us/dotnet/api/system.windows.splashscreen.close?view=netframework-4.8
[System.Security.SecurityCritical]
public void Close (TimeSpan fadeoutDuration);
Note: I am using the show method with the parameters AutoClose set to false, and TopMost set to true, this makes it not auto close as I want to close it programmatically and not subscribe to existing events.
I am running the lines of code from a Console (.NET framework) application for testing purposes before implementing it into my UI fully.
What I have tried:
Debugging and even trying to call show again before calling close.
It is definitely something going wrong with the class, as calling the class and directly manipulating the property works:
ClassSplashScreen rss = new ClassSplashScreen();
rss.splashscreen.Show(false);
rss.splashscreen.Close(TimeSpan.FromSeconds(1));
My best guess is something is hanging the UI and freezing it? But I am unsure what to do about it.
Code to run to test this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace NamespaceName
{
public class StackOverFlowCode
{
static void Main(string[] args)
{
ClassSplashScreen screen = new ClassSplashScreen();
screen.ShowSplashScreen();
screen.CloseSplashScreen();
}
}
public class ClassSplashScreen
{
public SplashScreen splashscreen { get; set; }
public ClassSplashScreen()
{
splashscreen = new SplashScreen("Resource Image Link");
}
public void ChangeSplashResource(SplashScreen resource)
{
splashscreen = resource;
}
public void ShowSplashScreen(bool autoClose = false)
{
splashscreen.Show(autoClose, true);
}
public void CloseSplashScreen()
{
splashscreen.Close(TimeSpan.FromSeconds(1));
}
}
}
The SplashScreen relies on a dispatcher but there is no one in a console application by default. If you create a System.Windows.Application, it should work as expected:
public class StackOverFlowCode
{
[STAThread]
static void Main(string[] args)
{
Application app = new Application();
app.Startup += (s, e) =>
{
ClassSplashScreen screen = new ClassSplashScreen();
screen.ShowSplashScreen();
screen.CloseSplashScreen();
};
app.Run();
}
}
public class ClassSplashScreen
{
private readonly SplashScreen splashscreen;
public ClassSplashScreen() => splashscreen = new SplashScreen("Resource Image Link");
public void ShowSplashScreen() => splashscreen.Show(false);
public void CloseSplashScreen() => splashscreen.Close(TimeSpan.FromSeconds(1));
}
class Program
{
public static string playerName;
static void Main(string[] args)
{
playerName = Console.ReadLine();
}
public static void userInterface()
{
Console.Writeline("Name:" + playerName)
}
}
Been trying to understand where im falling short for a few hours now and cannot figure it out, wondering if any of the SO residents can help me.
Im trying to display a inputted username in a GUI using C# console, I have defined it as a public variable in the class and called it in the method, however its throwing me this exception and displaying a null value?
Any help is appreciated.Class and Main The method im trying to call the variable to
EDIT the desired aim is to have the program display the users inputted username in the UI at the top of the console
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Player player = new Player
{
Name = "name coming from your input class"
};
UserInterface userInterface = new UserInterface(player);
}
}
class UserInterface
{
public UserInterface(Player player)
{
Console.SetWindowSize(220, 55);
Console.WriteLine("Name: {0}", player.Name);
}
}
class Player
{
public string Name { get; set; }
}
}
Or something alike. So you need to provide values for your variables.
Just call the method userInterface() after this line playerName = Console.ReadLine();
this will display the accepted value on console.
So I tried to create a new form and reference it...the compiler didn't mind this but it clearly wasn't changing the visibility of my picturebox. this is how I was calling my method found in my form, FROM my c# script.
Form1 updateForm = new Form1();
updateForm.setLights();
It called the method, and seemed like it worked! Until I read a post about instancing forms, and how by creating a "new" instance of Form1, that anything referenced by my updateForm would not change what I would see on my Form1.
So what I need to do is to call the function in setLights() which is in my Form1, and get it to change the visibility of my image on that form, from my C# code. Please see below (i understand the issue of the instancing problem mentioned above, but I left it in so that hopefully it will give better insight into what I am "trying" to do :) ALSO, please keep in mind that setLightCall() is running in a separate thread. Thanks in advance!
This code is also in my main c# script, and is the main function that I use to call my threads
static void Main(string[] args)
{
Thread FormThread = new Thread(FormCall);
FormThread.Start();
Thread setLightThread = new Thread(setLightCall);
setLightThread.Start();
log4net.Config.XmlConfigurator.Configure();
StartModbusSerialRtuSlave();
}
This code is in my main C# script
public void setLightCall(Form1 parent)
{
Form1 updateForm = new Form1();
while(true)
{
updateForm.setLights();
}
}
The below code is in my form1
public void setLights()
{
Input1GreenLight.Visible = false;
}
Here is an example of what I think you are wanting to try. Note the use of Invoking and delegates to be able to access the PictureBox's Visible method. I had to add the System.Windows.Forms Namespace to the Console Application to be able to access the instance of the Form that was created in the FormThread Method, this is assuming that you only have 1 Form in your FormCollection.
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Windows.Forms;
namespace ConsoleApplication59
{
class Program
{
static void Main(string[] args)
{
Thread FormThread = new Thread(FormCall);
FormThread.Start();
Thread.Sleep(2000); //Sleep to allow form to be created
Thread setLightThread = new Thread(setLightCall);
setLightThread.Start(Application.OpenForms[0]); //We can get by with this because just one form
Console.ReadLine();
}
public static void setLightCall(object parent)
{
Form1 updateForm = (Form1)parent;
while (true)
{
updateForm.Invoke(updateForm.setLights, new object[] { false });
}
}
public static void FormCall()
{
Application.Run(new Form1());
}
}
}
Form1
public partial class Form1 : Form
{
public delegate void Lights(bool state);
public Lights setLights;
public Form1()
{
InitializeComponent();
setLights = new Lights(setLightsDelegate);
}
public void setLightsDelegate(bool state)
{
Input1GreenLight.Visible = state;
}
}
I have decided to play a little bit with MEF2 and net3.5 and I have thought it would be easy but I am stuck now. Generally the idea of my toy is I want to have form containet where I am going to load form extensions and show them. I did this code
My extension:
using System.ComponentModel.Composition;
using System.Windows.Forms;
namespace MyExtantion
{
public interface IForm
{
void LoadForm(Form form);
}
[Export(typeof(IForm))]
public partial class MyExtantion : Form, IForm
{
public MyExtantion()
{
InitializeComponent();
}
public void LoadForm(Form form)
{
MdiParent = form;
Show();
}
}
}
and form container
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using System.Windows.Forms;
namespace FormsContainer
{
public partial class FormContainer : Form
{
public FormContainer()
{
InitializeComponent();
}
private CompositionContainer _container;
public interface IForm
{
void LoadForm(Form form);
}
[Import(typeof(IForm))]
public IEnumerable Forms { get; set; }
private bool Compose()
{
var catalog = new AggregateCatalog(
new AssemblyCatalog(Assembly.GetExecutingAssembly()),
new DirectoryCatalog("Extantions"));
var batch = new CompositionBatch();
batch.AddPart(this);
_container = new CompositionContainer(catalog);
try
{
_container.Compose(batch);
}
catch (CompositionException compositionException)
{
MessageBox.Show(compositionException.ToString());
return false;
}
return true;
}
private void FormContainer_Load(object sender, EventArgs e)
{
if (Compose())
foreach (IForm form in Forms)
{
form.LoadForm(this);
}
}
}
}
The problem is I can not load my extantion and I have this error
{"The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.\r\n\r\n1) No exports were found that match the constraint '((exportDefinition.ContractName = \"FormsContainer.FormContainer+IForm\") && (exportDefinition.Metadata.ContainsKey(\"ExportTypeIdentity\") && \"FormsContainer.FormContainer+IForm\".Equals(exportDefinition.Metadata.get_Item(\"ExportTypeIdentity\"))))'.\r\n\r\nResulting in: Cannot set import 'FormsContainer.FormContainer.Forms (ContractName=\"FormsContainer.FormContainer+IForm\")' on part 'FormsContainer.FormContainer'.\r\nElement: FormsContainer.FormContainer.Forms (ContractName=\"FormsContainer.FormContainer+IForm\") --> FormsContainer.FormContainer\r\n"}
How I can achieve it with MEF? and What I do wrong?
You are declaring the IForm interface in two different places.
If you only reference one interface that both are using this code works properly.