How to run a C# winform in an XNA C# project - c#

I am trying to use the PDFsharp library in an XNA game. The example code I am trying to get to work is:
static void Main()
{
Renderer renderer = new Renderer();
PreviewForm form = new PreviewForm();
form.RenderEvent = new PagePreview.RenderEvent(renderer.Render);
Application.Run(form);
}
But I don't know how to get this to run in XNA.
Is it possible to pass the graphics that are passed to the winform to the XNA graphics engine instead?

update 2
It appears that the original links to MSDN have been broken, I can't seem to find them on MSDN anymore, if someone does, please update the post. In the mean time you may want to check out this codeproject article -- http://www.codeproject.com/Articles/21330/Easy-Rendering-with-XNA-Inside-a-Windows-Form
update after a quick check, looks like the first link at (See also: XNA and WinForms) is the same one I found.
I recommend you look into mixing winforms and XNA, try this: http://create.msdn.com/en-US/education/catalog/sample/winforms_series_1

The First thing you need to do is to create the login form.
in this form create the fields you need as public properties
public string userName {get;set;}
public string password {get;set;}
in the login form you need to write the user info to those properties:
private void btnOk_Click(object sender,EventArgs e)
{
this.userName = txtName.Text;
this.password = txtPass.Text;
this.Close();
}
then, in the game (in the part you need) write something like this:
using (var form = new frmLogin())
{
var result = form.ShowDialog();
if (result == DialogResult.OK)
{
string user = form.userName;
string pass = form.password;
}
}
But as an FYI - winforms don't look so good in XNA
Hope it helps

Related

Moving Between One Form to Another - C#

I am currently creating a video game and coding the movement in a house between upstairs and downstairs. I'm using PictureBoxes in combination with an IntersectWith event to transition between forms.
Transition Code to go Upstairs:
if(picPlayer.Bounds.IntersectsWith(picUpstairsTransition.Bounds))
{
MapFrmHouseUpstairs upstairs = new MapFrmHouseUpstairs();
this.Hide();
upstairs.ShowDialog();
}
Transition Code to Go Back Downstairs:
if(picPlayer.Bounds.IntersectsWith(picGoDownstairs.Bounds))
{
MapFrmHouse goDownstairs = new MapFrmHouse();
this.Hide();
goDownstairs.ShowDialog();
picPlayer.Location = new Point(497, 103);
}
The issue I have is that when the player enters the house, he starts at the front. When he tries to come back from upstairs, the character is moved back to the front instead of the base of the stairs. Is there anyway I could create a method within MapFrmHouse such as:
public void fromDownstairs{picPlayer.Location = new Point(x,y);}
And call it when going downstairs?
First of all you'd better use a game engine to design games like Unity which is much easier and more fun. This might be a learning task for you though which I don't blame :)
You can send information between forms in Windows Forms in many ways, two of which seems to fulfill your needs:
Using a higher level modifier for objects
Initializing values in constructors
To do the first you set the modifier property of the picture box called picPlayer in your MapFrmHouse class from private to public then you can do exactly what you mentioned:
if(picPlayer.Bounds.IntersectsWith(picGoDownstairs.Bounds))
{
MapFrmHouse goDownstairs = new MapFrmHouse()
{
picPlayer.Location = new Point(x,y);
};
this.Hide();
goDownstairs.ShowDialog();
}
For the second method you should create an overload constructor in your MapFrmHouse and accept a Point value in it and then set it your value like this:
public MapFrmHouse(Point p)
{
InitializeComponent();
picPlayer.Location = p;
}
And then use it in your code like this:
if(picPlayer.Bounds.IntersectsWith(picGoDownstairs.Bounds))
{
MapFrmHouse goDownstairs = new MapFrmHouse(new Point(x,y));
this.Hide();
goDownstairs.ShowDialog();
}
I hope this helps :)

WPF validation of input (on-the-fly) and unit test. Best practice for design

I want to add a new form to an existing solution. The solution already has a Validator class, so I want to expand this class.
The Form I want to create contains a Textbox (for the input) and a Button. When the input is the correct format the submit button is enabled. The input must adhere to a certain regular expression: "^[A-Za-z]{2}[0-9]{5}$". I'm checking the input (on-the-fly) in the Form class like this:
private void inputTbx_TextChanged(object sender, TextChangedEventArgs e)
{
SubmitButton.IsEnabled = Validator.IsInputValid(inputTbx.Text, RegexExpression);
}
I've put the regular expression as a variable in the Form class. I put it here because it is relevant to the textbox of this form only.
private const string RegexExpression = "^[A-Za-z]{2}[0-9]{5}$";
Here's the validation code:
public static bool IsInputValid(string inputToBeChecked, string regexExpression)
{
if (inputToBeChecked == null || regexExpression == null)
{
return false;
}
var regex = new Regex(regexExpression, RegexOptions.None);
return regex.IsMatch(inputToBeChecked);
}
So far so good. It seems to work fine. But I want to unit test it like so:
[TestCase("aZ13579")]
public void ValidateInputOkTest(string input)
{
Assert.IsTrue(Validator.IsInputValid(input, RegexExpression));
}
But to do it like this I have to have a string in my ValidatorTest class similar to the Regular-expression used in the Form class. This doesn't seem like the right way to do it. What I really want to do is get the Regex expression from the form class, so I am sure it's the correct Regex-expression that I'm using. Otherwise the Regex-expressions could easily get out of sync.
Here are the questions:
What is best practice here?
How do I get to this expression? I've tried doing it using Reflection, but I get a Threadstat error because it's a GUI component. Should I move the Regular-expression? If so where to?
I'm thinking there must be a smart way to do this. A smart design perhaps. Suggestions and comments are welcome.
You're probably going to want to back up a step and start to research the 'MVVM' design pattern. When you hear people talk about putting no code in the code behind, testing like this is one of the big benefits (among many others).
MVVM is too big a topic to handle in a simple answer like this. I'd search around on the web, and I'm sure other people have some good tutorials.
Just to be clear, it can be a big learning curve, but it's totally worth it. MVVM is what makes WPF much much (MUCH) better than WinForms, rather than merely different.
Just to address your question a little more specifically, you won't be testing a GUI object like a Window or UserControl. You'll be testing a view model which is just a regular class.
Here's a simplified version of what you might see
public class MyScreenViewModel : INotifyPropertyChanged
{
private const string RegexExpression = "^[A-Za-z]{2}[0-9]{5}$";
public bool UserInputIsValid { get { stuff; } set { stuff; }}
public string UserInput { get { stuff; } set { stuff; ValidateUserInput();} }
private void ValidateUserInput()
{
if (UserInput == null)
{
return false;
}
var regex = new Regex(RegexExpression, RegexOptions.None);
UserInputIsValid = regex.IsMatch(UserInput);
}
}
A view model in MVVM is the real logic of your screen. It will expose simple properties that the view can bind to for display/input, but the view isn't necessary for testing the logic.
Then your test looks something like:
[TestCase("aZ13579")]
public void ValidateInputOkTest()
{
var vm = new MyScreenViewModel();
vm.UserInput = "SomeValidText";
Assert.IsTrue(vm.UserInputIsValid);
}
[TestCase("aZ13580")]
public void ValidateInputNotOkTest()
{
var vm = new MyScreenViewModel();
vm.UserInput = "SomeInvalidText";
Assert.IsFalse(vm.UserInputIsValid);
}

Curious as how to get a console inside of a windows form [duplicate]

This question already has answers here:
Embedding a DOS console in a windows form
(3 answers)
Closed 10 years ago.
Here's an axample
Just curious, I'm new with C#, but I decided to use it to develop my server for my Java game simply because I wanted a nice server-gui, but I'm starting to realize this would be just as easy to do with Swing...
I did a similar project over the weekend, I used this link to forward all Console data to a textbox. You could use any similar control with minor tweaks.
public class TextBoxStreamWriter : TextWriter
{
TextBox _output = null;
public TextBoxStreamWriter(TextBox output)
{
_output = output;
}
public override void Write(char value)
{
base.Write(value);
_output.AppendText(value.ToString()); // When character data is written, append it to the text box.
}
public override Encoding Encoding
{
get { return System.Text.Encoding.UTF8; }
}
}
All of the Write(...) and WriteLine(...) trickle down to Write(char) so it's the only method that you need to override.
My example required the form to also have a public TextBox property which exposed the private TextBox inside the form.
TextWriter consoleRedirect = new Tools.TextBoxStreamWriter(consoleForm.TxtOuputDisplay);
Console.SetOut(consoleRedirect);
Well I already wrote this up before I saw the previous comment. But since I took the time I will post it anyway.
public void WriteLog(TextBox tb ,string log)
{
tb.AppendText(log + "\n");
}
private void button1_Click(object sender, EventArgs e)
{
WriteLog(textBox1, "[App]: This is a log string");
WriteLog(textBox1, "[App]: Another log string");
WriteLog(textBox1, "[App]: Yet another etc etc.");
}
Where textBox1 is a Multi-line textbox with a black backcolor and blue foreground text.
The above comment is a more elegant solution but this will get you by if you want something quick and easy. I dont have enough rep to post an image inline but here is what it looks like. http://imageshack.us/photo/my-images/198/logwindow.jpg/

Single reusable function to open a single instance of form

I am trying to create a reusable function that can open a single instance of form. Means if a form is not already open it should create and show the new form and if already open it should bring the existing form to front.
I was using the following function,
if (Application.OpenForms["FPSStorageDemo"] == null)
{
FPSStorageDemo fp = new FPSStorageDemo();
fp.Name = "FPSStorageDemo";
fp.Show();
}
else
{
((FPSStorageDemo)Application.OpenForms["FPSStorageDemo"]).BringToFront();
}
But I have to write this code again and again whereever I have to open a form. But I need a single reusable function that can do this job.
I wrote a function like,
void OpenSingleInstanceForm(Type TypeOfControlToOpen)
{
bool IsFormOpen = false;
foreach (Form fm in Application.OpenForms)
{
if (fm.GetType() == TypeOfControlToOpen)
{
IsFormOpen = true;
fm.BringToFront();
break;
}
}
if (!IsFormOpen)
{
Object obj = Activator.CreateInstance(TypeOfControlToOpen);
//obj.Show(); //Here is the problem
}
}
But at the end I don't know how to show the new form instance. Can anybody suggest how to do it? Is this wrong or there is another way to do this?
Thanks in advance.
public static class FormUtility
{
public static FormType GetInstance<FormType>() where FormType : Form, new()
{
FormType output = Application.OpenForms.OfType<FormType>().FirstOrDefault();
if(output == null)
{
output = new FormType();
}
//you could add the show/bring to front here if you wanted to, or have the more general method
//that just gives a form that you can do whatever you want with (or have one of each).
return output;
}
}
//elsewhere
FormUtility.GetInstance<Form1>.BringToFront();
I'd also like to take the time to mention that while having methods like this are quick and easy to use, in most cases they are not good design. It leads you to the practice of just accessing forms globally rather than ensuring that when forms need to communicate with each other they do so by exposing the appropriate information through the appropriate scope. It makes programs easier to maintain, understand, extend, increases reusability, etc. If you have trouble determining how best for two or more forms to communicate without resorting to public static references to your forms (which is exactly what Application.OpenForms is) then you should feel free to post that question here for us to help you solve.
You are looking for Singleton
Check this Implementing Singleton in C#

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