
As you know, xna does not provide a typical GUI, so each developer has to decide whether to draw it themselves, connect ready-made GUI libraries developed specifically for xna (there are not too many of them), or try to connect standard winform / wpf (there is already a wonderful wpf connection
article ).
I did not begin to understand the numerous options for solving this problem and decided to go as it seemed to me the easiest way - by connecting a winform. As it turned out, winform has a number of nuances and limitations.
In the end, after an active search, I came to two possible implementations of the interface:
1. The entire interface without the keyboard, i. buttons, lists, etc. If you need to enter something from the keyboard - create an external form and receive data from it.
2. The interface is fully functional and you can enter data from the keyboard. But the creation of external forms is impossible + a couple more nuances.
More details:
one
In the xna project you need to add links to System.Windows.Forms and System.Drawing. Then prescribe the code for creating the necessary controls. Controls will not respond to keystrokes. I could find the reason for this behavior on the Internet, but unfortunately I did not find a satisfactory solution, quote:
XNA uses its class to listen to the keyboard status, while the textbox uses the Windows.Form.Input
.
The author of the quotation resolved this issue by creating a method that directly receives the pressed buttons through the built-in xna class and directly sends it to the input field of the selected control. The disadvantage of this approach is that there is no easy way to find out if the “Q” or “Y” key is pressed (For details on the method, see link 1 at the bottom of the article).
Connection of the control to the form:
')
using Size_ = System.Drawing.Size; // A reference to System.Drawing has been added to the solution browser, but here only the size and position is needed from the entire namespace
using Point_ = System.Drawing.Point;
...
...
// Create control
NumericUpDown nm = new NumericUpDown ();
nm.Location = new Point_ (0, 50);
nm.Size = new Size_ (125, 20);
nm.Value = ( decimal ) text2;
nm.KeyUp + = new KeyEventHandler (nm_ValueChanged_f);
nm.ValueChanged + = new EventHandler (nm_ValueChanged_f);
// Get the current form
Form general_form = (Form) Control.FromHandle (Window.Handle);
// Connect the control to the current form
general_form.Controls.Add (nm);* This source code was highlighted with Source Code Highlighter .Sources of a simple application with controls inside the form and creating an external form at the end of the article.
2
The method described above unfortunately cannot be applied to applications that require user input of text. Continuing the search, I found a different connection method winform (link 2 at the end of the article). Its essence lies in the fact that the initialization of the form, controls, and only then - the game itself. The peculiarity is that in this way the game will not be able to call the update () and draw () methods - they will need to be called separately.
This method is suitable for many tasks, because All created controls will correctly respond to keystrokes.
However, this method has nuances.
All controls should be created after (during) the initialization of the form, but prior to the initialization of the game itself (it is necessary to hide the unnecessary at a particular moment through Visible). The controls created after the initialization of the game form (the form of the application and the game form are different forms, although this is not visible visually), will not accept keystrokes, I could not find out the reason for this, unfortunately. This also applies to the creation of forms subordinate to the game form - they will be visible, but the textbox and similar controls will not work. Also, the controls created after the initialization of the game form may not be visible at all if they are subordinate to the form of the application, and not the game form.
To create top-level forms for this approach is useless - they will actually be inoperable (they are very slow).
Of the shortcomings of this approach, I can also point out a barely noticeable drop in performance.
The code is relatively large so I did not post it in the article. The source code of the example can be downloaded below (example 2).
I will be glad to add and constructive criticism!
References:
1. Solution of unavailability of keyboard input by entering a special method2. The way of connecting the controls “vice versa” - first the initialization of the controls, then the games.3. Description of the method similar to the 1st in the Russian-speaking community xnaDownload example 1Download example 2