Efficiently creating UI elements from XML file (OpenGL / C# NET 6.0) - c#

I'm currently working on a small game framework, build on top of OpenTK. In this project there should also be a way to easily create UI elements by defining their layout in an XML file, like WPF and XAML but way less complex (no bindings planned etc).
Now I'm kind of stuck when it comes to efficiently creating these ui elements from the XML file. The concept is that there are few core elements like image, label and panes for layouting and the structure of all more complex elements are defined in XML and represented by a seperated class (that inherits from UIElement, the base class for all UIElements).
For example, this is how it could look like for a button:
Button.xml
<Button Layout="AlignLayout Stretch Stretch">
<Image Name="image"></Image>
<Image Name="hoverImage"></Image>
<Image Name="pressedImage"></Image>
<AlignPane HorizontalLayout="Center" VerticalLayout="Center">
<Label Name="label"
IgnoreInputEvents="true">
</Label>
</AlignPane>
</Button>
Button.cs
public class Button : UIElement
{
protected Image image;
protected Image hoverImage;
protected Image pressedImage;
protected Label label;
public Button(UIElement? parent, Texture2D backgroundTexture,
Texture2D hoverTexture, Texture2D pressedTexture,
string text) : base(parent)
{
// Receive XML layout here probably? (from cache, not parsed)
image.Texture = backgroundTexture;
hoverImage.Texture = hoverTexture;
pressedImage.Texture = pressedTexture;
label.Text = text;
// ...
}
}
and the usage in code would simply be:
Button startButton = new Button(OverlayUICanvas, bgTex, hovTex, prsTex, "Start");
or use the element in some other XML file.
The element attributes in xml set properties in the corresponding class (except "Name", which is expected to set the fields/properties in the root element to the instance of the created class)
Basically i got something like this working already except that it is super inefficient (probably because all the reflection going on including parametered constructor calls). While testing it took over 100ms to load something simple with just 8 total elements.
It wouldn't be too bad if i could somehow cache the loaded layout somehow and then just create a new instance, without all the reflection going on again (layout would be loaded at game start or something) but i really have no clue how i could archive this.
Creating new instance of these elements is pretty important: imagine the game needs to creates some elements at runtime from a list or something like that.
I didn't really found any good information on how to do this, not even sure if it is possible like that. If I undestood correctly, WPF solves this by generating some source code on compilation but it stated this only works for netstandard2.0 and I'm having a hard time wrapping my head around if this would even help me solve this problem.
If you want to take a look at the current source yourself for some reason:
https://github.com/BlakkM9/VengineX/tree/master/VengineX/UI
but please keep in mind - this project is WIP, in a very very early state and nothing professional, really.
I'm graceful for any tips and hints that might lead me in the right direction!

Related

Generating Form Elements in code

I have a web app that has a form on just about every page. In order to make sure each form renders the same, as to make changes easier, I want to render all of my form controls in c# in a central place so if I need to add a class to the input or change something, I only have to do it once.
At the moment, I am just using a load of static classes like TextInputHelper, CheckboxInputHelper etc that use StringBuilder to build up the HTML and returns a string to my view.
For example, all of my forms controls are of the basic form:
<section>
<label class="label">Label Text</label>
<label class="input">
...Input Element...
</label>
</section>
What I would like to do is improve this situation as I still have a lot of duplication between the different helper classes, particularly for the wrappers to the form elements. My initial thoughts are to have a class called something like BaseFormControl that has a virtual Render method that has the outer wrapper for the control, then create other classes that implement this to do specific things like a TextFormControl that puts
<input type="text".....
inside the wrapper.
Am I on the right path for this, and/or is there a design pattern that is appropriate for what I want to do?
From my POV what I read is that you over complicating your server side just because of a CSS/HTML standardization that be easily solved from the client side.
If you still want to go for the server side approach the pattern that seems to apply to your approach is the Adapter(Wrapper) pattern meaning that you probably would want to create control wrapper clases to meet your needs for each control that renders a different html from what is offered by ASP.NET built-in controls.
If what you want to do instead is to format a group of controls then a UserControl is way much better approach.
Remember that ASP.NET was build with the spirit of trying to keep layers separated the View from the Code therefore any attempt to generate html from the server side has to be an exception and not a rule.

Mono.TextEditor highlight line

I am making a pascal code editor in Mono in MonoDevelop. I am using Mono.TextEditor as a code editor widget. However, I cannot find how to highlight a line in the widget.
After compilation, I collect line numbers where errors occur, and so I want to highlight them in red. I found
Mono.TextEditor.LineBackgroundMarker
which seems to relate to what I want to do, but I cannot find where and how to use it.
Another option I was looking into was ViBuilder, but I don't even know how to use that. I can think of two ways to solve this problem:
Simply make highlight
Mark a line as error, as default style includes:
{ "name": "Underline(Error)", "color":"invalid-red" }
which also seems to be a possible solution.
You can highlight lines in the text editor by adding markers to the underlying document. Use the TextDocument.AddMarker method, as follows:
TextEditor textEditor;
var marker = new Mono.TextEditor.LineBackgroundMarker();
int lineNumber = ...;
textEditor.Document.AddMarker(lineNumber, marker);
textEditor.QueueDraw();
Also have a look at the Mono.TextEditor.StyleTextMarker class. This class has already the properties "BackgroundColor" / "Color" that you are looking for. Underlining may have to be done manually (for example by inheriting from StyleTextMarker and overriding the Draw method).

Xamarin Monodroid: WP7 => Android and Custom Control?

i am in the process of porting some of my Windows Phone Applications to Android using Xamarin Monodroid.
I am pretty new with the Xamarin stuff, just bought a license actually.
So far so good as far as recreating the XAML UI in AXML but i am facing a problem with Custom Controls.
Here is what i mean by custom controls:
In .NET, i created a bunch of controls by creating class that inherit from the 'UserControl' class, i created the logic and set the Content. Then i just create new instance with 'new my_control()', etc...
Some of my controls are not created this way but instead i created the UserControl by defining the XAML, where there is no specific logics but when i need to combine 2 or more controls(for example, a colored square with text beside it, so Rectangle + TextBlock) and again i just need to do 'new my_control()' and add it somewhere in the XAML UI(Grid, ListBox, StackPanel, etc...).
How can i achieve something similar with Monodroid?
Thanks in advance!
You can make your own custom view by inheriting the View class. This allows you to do anything. Then you can reference it in your AXML with:
<your.awesome.namespace.AwesomeViewName
android:id="#+id/awesomeView"
android:layout...
/>
Just make sure your namespace name in the AXML is all lower case, otherwise it won't pick it up.
But if you just need a very simple AXML layout that you are going to use a lot, you can create a new AXML file and use the include tag to put it in there.
There is some more general info on some Layout Tricks for Android which will work for Mono for Android as well here: https://developer.android.com/resources/articles/layout-tricks-merge.html
You can do "custom controls" in Mono for Android too - and once you've written them, then you can include them in your axml files.
I'm afraid I don't have any perfectly simple examples to hand, but there's a complicated example in:
https://github.com/slodge/MvvmCross/blob/master/Sample%20-%20CirriousConference/Cirrious.Conference.UI.Droid/Resources/Layout/ChildPage_Twitter.axml
If you declare a class MyControl in MyNamespace and inherit that control from an Android View and you can then setup your custom control - including pulling in attributes from the XML - using a constructor like:
public MyControl(Context context, IAttributeSet attrs) { /* ... */ }
and using XML like:
<mynamespace.MyControl android:layout_height='wrap_content' />
One example of this could be the control from https://github.com/Cheesebaron/MonoDroid.HorizontalPager - which could be used from xml using xml like
<mynamespace.controls.HorizontalPager
android:id="#+id/MyPageHost"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
Any reason why it won't enter the constructor? Here is my constructor:
protected CropImageView(IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
{
}
The Init method causes the circular dependency when I inflate the crop_image_view xml
I have tried with public, private but no luck... here is my code: https://github.com/slown1/Xamarin.CircleImageCropper

HtmlGenericControl("a") vs. HtmlAnchor

I was looking into why one of my applications was running quite slowly. The application generates and displays a grid and populates it with work tasks (rendered as table cells). Inside each task there is an <a href="... which brings up some more info about the task.
As this is all built up dynamically from the codebehind, I've used HTMLTableRows/Cells to create the rows and cells, then used the Controls properties to add HTMLAnchors. Whenever I'm setting attributes I've used HTMLAnchor.HRef, HTMLTableCell.ColSpan, etc.
I noticed that if I use the generic HTMLGenericControl and then use its Attributes collection, e.g.
HTMLGenericControl a = new HTMLGenericControl("a");
a.Attributes["href"] = task.getLink();
it runs significantly quicker than what I would have thought is the preferred way of doing the same thing:
HtmlAnchor a = new HTMLAnchor;
a.HRef = task.getLink();
Does anyone have any explanation for where this apparent extra 'overhead' comes from?
EDIT
In case anyone is confused by my explanation, I posted another question for the same project, which has a screenshot.
#subkamran I had the same thought, but after looking it up, actually both HTMLAnchor and HTMLGenericControl are sub-classed from the same parent: HTMLContainerControl. One significant difference is that HTMLAnchor implements the IPostBackEventHandler to handle the "ServerClick" event. This surely adds something to the slowness ...

ASP.NET user control designer support

I have a user control which when added to the markup via the Toolbox or manually typing
<myNameSpc:myCtrl ... I would like to spit out:
<myNameSpc:myCtrl>
<template></template>
</myNameSpc:myCtrl>
I remember doing this for windows workflows and it involved implementing something like a TypeConverter and WorkflowXmlSerializer so it maybe possible for user controls as well I'd guess ? the only thing is that I don't have time to research this matter now, so I was wondering if anyone would be kind enough to point me in the right direction so that I don't have to dig deep into the designer serialization of VS (which I remember was a big pain).
For your custom control, you can specify a ToolboxDataAttribute which defines the default html that will be generated when you drag a control onto the design service. E.g.:
[ToolboxData("<{0}:myCtrl runat="server"><template></template></{0}:myCtrl>")]
public class myCtrl : System.Web.UI.Control
{
}
For the manual generation you can create a Code Snippet. The best way to do that is find existing ASPX snippet and modify it to gen your control. I'm assuming you are using VS 2010.

Categories

Resources