I'm looking to build a website that works in the same manner that I have put together in this video, that isn't based on JS ( like it is in this video ), that can utilize C# in order to interop with JS and get windowWidth and windowHeight, and then dynamically change all of the CSS variables so that all of the content, images, and font size/shading/border/shadows, etc... will all scale as the page is zoomed in or out.
The end result is, to make a size that works for a single resolution and then scales all the way down to the 320w to 3200w resolutions out there. That means, one website, one template, no messing around with a thousand different iterations of the way the site should look.
I spent about a week trying to develop some C# code that could in fact change and set the variables, however, I'm not a seasoned C# veteran, I prefer to write everything in PS.
I understand the limitations of Blazor, and how it 'diffs' the state changes upon rendering, but if BlazorStyled can modify the CSS, then I see no reason why it would be impossible for the window width/height to directly influence the variables that the site runs off of.
I did study drafting and design, I left the field before I was able to study programming and C#/.Net in order to further what I could do with HTML and CSS more than a decade ago... same goes for the MCSE/MCSA curriculum that I also gave up on...
...but I've spent the last year 'catching up' on all of it.
https://youtu.be/Z99zsCwYhWk <- this is what I am attempting to perform in Blazor. This is utilizing javascript and document.queryselector, document.setproperty... I am not certain that it is possible to do these things either with or without JSInterop, and yes... i know how to change the css types with media queries... I'm attempting to build a forloop that captures every possible resolution out there and scales for every pixel within that loop.
But also, considers the fact that the layouts can have multiple formats that correspond to these dynamic variables. So as I've showcased in the video, below 720w the navigation bar will shift to the top, which can be done with native CSS media queries, but what can't be done is changing the DOM elements without screwing up the way Blazor works. I've tried. Even spent a week trying to write the C# code that would use JSInterop and the custom classes and dimensions and change the properties accordingly...
Upon compile... it said "I have failed." It said it a few times... So I was like damn. Spent a whole week trying to do something super cool... and this program looked at me and said "Bro. I don't like this input..."
But what can I do?
Given the nature of ASP.Net/Blazor, I won't post the code because there's a lot of content. I can give you a run down of what I have tried so far...
I found Chris Sainty's old project on github called "browserResize". But I think this breaks the rules of Blazor component [quantization and hyperspeed time space continuum effect displacement of the thermodynamic laws of physics ... everything in these brackets is comic relief]
I already had a fully blown javascript file that had all of the operations I needed inside, but, how do you get Blazor to work when the official Microsoft Blazor FAQ says
"Don't use JS for all that... cause that's lame." -Microsoft
After I read that quote that Microsoft put into the official FAQ... I thought... well, it's time to give it a grade A try anyway ... so I then implemented some classes that create objects in a similar manner to
```
# Heroes in a half 'Shell #
[PSCustomObject]#{
width = "window.innerWidth"
height = "window.innerHeight"
}
```
...only it is a lot more than that.
I made some JSInterop calls based on Nick Chapas' videos about it, and I'm pretty sure that I wrote all that correctly...? Not certain.
Then I made a service that could, upon resizing the window, set all of the corresponding CSS elements, and theoretically change the CSS styling of everything on the page given the conditions I showcase in the video link above.
I'm sure I may have overexplained what I'm attempting to do...? But, I'm burning a lot of time theorizing, not enough 'actually getting work done'. And, there comes a point in time where you may in fact be learning a great deal on new ways to get nowhere... but the case could also be made that 'there are better ways to make use of your time...'
Plz help. Thx bros.
(Edit: At the request of Iraklis, here are the two bits of code I made)
.\ - represents the base repo folder.
.\Data\Controller.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.JSInterop;
namespace ShellBlaze.Data
{
public class Controller
{
public static readonly IJSRuntime JSR;
public class Window
{
public async Task<int> Height()
{
return await JSR.InvokeAsync<int>( "getHeight" );
}
public async Task<int> Width()
{
return await JSR.InvokeAsync<int>( "getWidth" );
}
public async Task<object> QuerySelect( string Tag )
{
return await JSR.InvokeAsync<object>( "querySelect" , Tag );
}
public async Task SetProperty( object ID , string Property , string Value )
{
await JSR.InvokeVoidAsync( "setProperty" , ID , Property , Value );
}
}
public class Stage
{
Controller.Window Windex = new Controller.Window();
Model.Window Win = new Model.Window();
Model.Layout Lay = new Model.Layout();
public async Task<Model.Layout> Action()
{
Win.Height = await Windex.Height();
Win.Width = await Windex.Width();
Win.Side = Win.Width * 0.15f;
Win.Main = Win.Width * 0.85f;
Win.Pixel = Win.Width / 1920;
var Root = Windex.QuerySelect( ":root" );
int[] Ct = { 0, 1, 2, 3 };
string[] Element = { "root" , "side" , "main" , "pixel" };
double[] Unit = { Win.Width , Win.Side , Win.Main , Win.Pixel };
string[] Name = { "#top", "#side", "body" , "#main" };
string[] Property = { "display", "display", "flex-direction", "--content" };
string[] Value = new string[3];
string[] Value1 = { "flex", "none", "column", Win.Width + "px" };
string[] Value2 = { "none", "flex", "row", Win.Main + "px" };
if (Win.Width < 720)
{
Value = Value1;
}
else
{
Value = Value2;
}
foreach (int i in Ct)
{
await Windex.SetProperty( Root, "--" + Element[i], Unit[i] + "px" );
await Windex.SetProperty( Windex.QuerySelect( Name[i] ), Property[i], Value[i] );
}
if (Win.Width > 720)
{
Lay.Type = "top";
Lay.Logo = "toplogo";
Lay.ID = "ti";
Lay.Class0 = "t0";
Lay.Class1 = "t1";
Lay.Class2 = "t2";
Lay.Class3 = "t3";
Lay.Class4 = "t4";
Lay.Class5 = "t5";
Lay.Class6 = "t6";
Lay.String0 = "Home";
Lay.String1 = "App Development";
Lay.String2 = "Network Security";
Lay.String3 = "Enterprise";
Lay.String4 = "OS Management";
Lay.String5 = "Hardware";
Lay.String6 = "Data Management";
return Lay;
}
else
{
Lay.Type = "side";
Lay.Logo = "sidelogo";
Lay.ID = "si";
Lay.Class0 = "t0";
Lay.Class1 = "t1";
Lay.Class2 = "t2";
Lay.Class3 = "t3";
Lay.Class4 = "t4";
Lay.Class5 = "t5";
Lay.Class6 = "t6";
Lay.String0 = "Home";
Lay.String1 = "App<br/>Development";
Lay.String2 = "Network<br/>Security";
Lay.String3 = "Enterprise";
Lay.String4 = "OS<br/>Management";
Lay.String5 = "Hardware";
Lay.String6 = "Data<br/>Management";
return Lay;
}
}
}
public class State
{
public static event Func<Task> Trip;
[JSInvokable]
public static async Task Set()
{
Controller.Stage Stage = new Controller.Stage();
await Stage.Action();
await JSR.InvokeAsync<object>( "setEvent" );
await Trip?.Invoke();
}
}
}
}
.\Data\Model.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ShellBlaze.Data
{
public class Model
{
public class Layout
{
public string Type { get; set; }
public string Logo { get; set; }
public string ID { get; set; }
public string Class0 { get; set; }
public string Class1 { get; set; }
public string Class2 { get; set; }
public string Class3 { get; set; }
public string Class4 { get; set; }
public string Class5 { get; set; }
public string Class6 { get; set; }
public string String0 { get; set; }
public string String1 { get; set; }
public string String2 { get; set; }
public string String3 { get; set; }
public string String4 { get; set; }
public string String5 { get; set; }
public string String6 { get; set; }
public Layout()
{
Type = null;
Logo = null;
ID = null;
Class0 = null;
Class1 = null;
Class2 = null;
Class3 = null;
Class4 = null;
Class5 = null;
Class6 = null;
String0 = null;
String1 = null;
String2 = null;
String3 = null;
String4 = null;
String5 = null;
String6 = null;
}
public Layout(
string _Type,
string _Logo,
string _ID,
string _Class0,
string _Class1,
string _Class2,
string _Class3,
string _Class4,
string _Class5,
string _Class6,
string _String0,
string _String1,
string _String2,
string _String3,
string _String4,
string _String5,
string _String6
)
{
Type = _Type;
Logo = _Logo;
ID = _ID;
Class0 = _Class0;
Class1 = _Class1;
Class2 = _Class2;
Class3 = _Class3;
Class4 = _Class4;
Class5 = _Class5;
Class6 = _Class6;
String0 = _String0;
String1 = _String1;
String2 = _String2;
String3 = _String3;
String4 = _String4;
String5 = _String5;
String6 = _String6;
}
}
public class Sheet
{
public object ID { get; set; }
public string Tag { get; set; }
public string Property { get; set; }
public string Value { get; set; }
public Sheet()
{
ID = null;
Tag = null;
Property = null;
Value = null;
}
public Sheet( object _ID , string _Tag , string _Property , string _Value )
{
ID = _ID;
Tag = _Tag;
Property = _Property;
Value = _Value;
}
}
public class Window
{
public int Height { get; set; }
public int Width { get; set; }
public double Side { get; set; }
public double Main { get; set; }
public double Pixel { get; set; }
public Window()
{
Height = 0;
Width = 0;
Side = 0.00f;
Main = 0.00f;
Pixel = 0.00f;
}
public Window( int _Height , int _Width , double _Side , double _Main , double _Pixel )
{
Height = _Height;
Width = _Width;
Side = _Side;
Main = _Main;
Pixel = _Pixel;
}
}
}
}
.\Scripts\script.js
function querySelect(Tag)
{
return document.querySelector( '"' + Tag + '"' );
}
function setProperty(ID, Property, Value )
{
ID.style.setProperty( "'" + Property + "'" , "'" + Value + Unit + "'" );
}
function getHeight()
{
return window.innerHeight;
}
function getWidth()
{
return window.innerWidth;
}
function setEvent()
{
DotNet.invokeMethodAsync( "Resize" , "Set" ).then(data => data);
window.addEventListener( "resize" , setEvent() );
}
Related
I am using a model named as Mdl_home_page the model consist of bunch of properties like :
public class Mdl_home_page
{
public SelectList LocationSelectList { get; set; }
public List<tbl_devices> lstOfDevices { get; set; }
}
The tbl_devices is my another model which contains information about devices.
The tbl_device model is :
public partial class tbl_devices
{
public int device_id { get; set; }
public string device_name { get; set; }
public string device_ip { get; set; }
public string device_type { get; set; }
public string device_placement_coordinates_x { get; set; }
public string device_placement_coordinates_y { get; set; }
}
I passed the model to the view like this:
#model SymphonyWebServer.Models.Mdl_Home_page
Now I have a HTML canvas on which I have an image of map where I want to display the rectangles to depict placement of a device. to do this I want to use device_placement_coordinates_x and device_placement_coordinates_y properties of tbl_device model.
So, I made a code like :
var xvalue = 100, yvalue = 100;
for (var i = 0; i < #Model.lstOfDevices.Count; i++) {
xvalue = #Model.lstOfDevices[i].device_placement_coordinates_x;
yvalue = #Model.lstOfDevices[i].device_placement_coordinates_y;
ctx.fillRect(xvalue, yvalue,50,50);
}
ctx is my context object of the canvas.
But It is giving me error: the name 'i' does not exist in the current context.
Please help to resolve the problem !
The variable i is an JavaScript variable. You can't use it as the index in the C# listOfDevices array.
Why not just loop through the array using foreach, and run JavaScript code inside? You can use #: or <text /> to switch between C# Razor mode and JavaScript mode.
var xValue = 100, yValue = 100;
#foreach (var device in Model.lstOfDevices)
{
<text>
xValue = #device.device_placement_coordinates_x;
yValue = #device.device_placement_coordinates_y;
ctx.fillRect(xValue, yValue, 50, 50);
</text>
}
I have the following javascript code:
var key = "Mykey" + NextNumber.toString();
var value = {"Name":"Tony","Width":"150","Height":"320"};
var valuejson = JSON.stringify(value);
var obj = {};
obj[key] = valuejson
I know how to create valuejson in C#, but I don't know how to create something similar like var obj = {}; in C#. How can I do that in C#?
key and valuejson in C#:
public class MyValue
{
public string Name { get; set; }
public string Width { get; set; }
public string Height { get; set; }
}
MyValue value = new MyValue();
value.Name = "Tony";
value.Width = "150";
value.Height = "320";
string jsonValue = JsonConvert.SerializeObject(value);
string key = "Mykey" + NextNumber.toString();
You could try to use a dynamic object which works similar to {} in javascript... But... You have to be CAREFUL, example:
public class test
{
public class MyValue
{
public string Name { get; set; }
public string Width { get; set; }
public string Height { get; set; }
}
public void testing()
{
MyValue value = new MyValue();
value.Name = "Tony";
value.Width = "150";
value.Height = "320";
dynamic jsonValue = new { keyA = value };
string height = jsonValue.keyA.Height;
}
}
EDI:
Actually, I read a bit more carefully your need, and a dictionary can also suit your needs:
public class test
{
public class MyValue
{
public string Name { get; set; }
public string Width { get; set; }
public string Height { get; set; }
}
Dictionary<string, MyValue> dic = new Dictionary<string, MyValue>();
public void testing()
{
string key = "Mykey" + NextNumber.toString();
MyValue value = new MyValue();
value.Name = "Tony";
value.Width = "150";
value.Height = "320";
dic.Add(key, value);
}
}
Since you where asking for the equivalent of a var x = {} I suggested the dynamic but I see you want to create a key and associate that value to that key.
If you're looking for an object whose members can be dynamically added and removed at run time (like in Javascript) then the ExpandoObject class should fit your needs.
dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;
foreach (var property in (IDictionary<String, Object>)employee)
{
Console.WriteLine(property.Key + ": " + property.Value);
}
// This code example produces the following output:
// Name: John Smith
// Age: 33
You are asking for dynamic ExpandoObject.
Example:
dynamic obj = new ExpandoObject();
obj.banana = "CIAO";
obj.bidshmqwq = 11245;
obj.BRUFCJMWH = null;
In substance, this Type can let you declare object's properties dynamically.
To convert from a json string to a C# object, you can use the DeserializeObject method and pass in an instance of the c# object that you want to convert this json to. The JsonConvert library is part of the Newtonsoft.Json library.
var converted = JsonConvert.DeserializeObject<myCSharpViewModel>(json);
I'm running through a WintellectNOW course on ASP.NET Core/Web API/Angular 2. I have the API portion implemented, but for whatever reason, the JSON that is being returned has the variable names being lowercased.
The returned JSON is formatted like...
[
{"id":1,"name":"Bowler","color":"black","count":1},
{"id":2,"name":"Fedora","color":"red","count":1},
{"id":3,"name":"Baseball Cap","color":"blue","count":3}
]
I'm expecting...
[
{"Id":1,"Name":"Bowler","Color":"black","Count":1},
{"Id":2,"Name":"Fedora","Color":"red","Count":1},
{"Id":3,"Name":"Baseball Cap","Color":"blue","Count":3}
]
Based on the C# model of...
namespace HatCollection.Models
{
public class Hat
{
public int Id { get; set; }
public string Name { get; set; }
public string Color { get; set; }
public int Count { get; set; }
}
}
I even went as far as decorating the properties with [DataMember(Name = "Id")] just to make sure and it still didn't matter.
On the off chance, it's relevant the Action and instance variable in the controller...
private static readonly List<Hat> MyHats = new List<Hat>
{
new Hat {Id = 1, Name = "Bowler", Color = "black", Count = 1 },
new Hat {Id = 2, Name = "Fedora", Color = "red", Count = 1 },
new Hat {Id = 3, Name = "Baseball Cap", Color = "blue", Count = 3 }
};
[HttpGet]
public IEnumerable<Hat> Get()
{
return MyHats;
}
How do I turn off the camelCase functionality, so that ASP.NET Core returns the property names without changing them?
In Asp.Net Core 3.0 some things have changed. For camelCase do nothing that is out of the box. For PascalCase or another set style use.
services.AddMvc(setupAction=> {
setupAction.EnableEndpointRouting = false;
}).AddJsonOptions(jsonOptions =>
{
jsonOptions.JsonSerializerOptions.PropertyNamingPolicy = null;
})
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
In Startup.cs ConfigureServices section
For those who needs a solution about a PascalCase within Api Project that has not the Mvc services you should add this after AddControllers services
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers().AddJsonOptions(jsonOptions =>
{
jsonOptions.JsonSerializerOptions.PropertyNamingPolicy = null;
} ;
}
For Asp.Net Core 3.1 using the NewtonSoft.Json
services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.UseMemberCasing();
});
In ASP.NET Core <3.0, JSON properties are camelCased by default (per this announcement).
You can disable this by replacing
services.AddMvc();
with
services
.AddMvc()
.AddJsonOptions(opt => opt.SerializerSettings.ContractResolver
= new DefaultContractResolver());
in your Startup.cs file. You'll have to add using Newtonsoft.Json.Serialization; to the top of the file.
With the DefaultContractResolver in place, the property names will be represented verbatim in the JSON output. No need for DataMember attributes.
Here is the answer for .net 5 :
https://learn.microsoft.com/en-us/aspnet/core/web-api/advanced/formatting?view=aspnetcore-5.0
Configure System.Text.Json based formatters Features for the
System.Text.Json based formatters can be configured using
Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions.
The
default formatting is camelCase. The following highlighted code sets
PascalCase formatting:
C#
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddJsonOptions(options =>
options.JsonSerializerOptions.PropertyNamingPolicy = null);
}
Another solution in Asp.Net.Core 2.2 as following:
services.AddMvc()
.AddJsonOptions(jsonOptions => jsonOptions.UseMemberCasing())
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
In ASP.Net Core you can use two way:
First way: UseMemberCasing()
In StartUp.cs :
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews().AddNewtonsoftJson(opt =>
{
opt.UseMemberCasing(); // <-- add this
});
}
Second way: ContractResolver
In StartUp.cs :
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews().AddNewtonsoftJson(opt =>
{
opt.SerializerSettings.ContractResolver = new DefaultContractResolver(); // <-- add this
});
}
depends on your project maybe you used AddMvc() or AddControllers() insted of AddControllersWithViews().
If AddNewtonsoftJson not found, you should install Nuget pacage : Microsoft.AspNetCore.Mvc.NewtonsoftJson (link).
You have to change the DefaultContractResolver which uses camelCase by default. Just set the NamingStatergy as null.
This should be done in the StartUp.ConfirgureService as follows.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddMvcOptions(o => o.OutputFormatters.Add(
new XmlDataContractSerializerOutputFormatter()));
.AddJsonOptions(o => {
if (o.SerializerSettings.ContractResolver != null)
{
var castedResolver = o.SerializerSettings.ContractResolver
as DefaultContractResolver;
castedResolver.NamingStrategy = null;
}
});
}
Option 2
Use JSonProperty as follows.
public class Hat
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("color")]
public string Color { get; set; }
[JsonProperty("count")]
public int Count { get; set; }
}
I am using the following solution because
a) I prefer using the .Net Core built in System.Text.Json serializer and
b) I do not want to rely on the not documented internal behaviour of
jsonOptions.JsonSerializerOptions.PropertyNamingPolicy = null;.
.
services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy = new MyTransparentJsonNamingPolicy();
});
where:
public class MyTransparentJsonNamingPolicy : JsonNamingPolicy
{
// You can came up any custom transformation here, so instead just transparently
// pass through the original C# class property name, it is possible to explicit
// convert to PascalCase, etc:
public override string ConvertName(string name)
{
return name;
}
}
In .NET 6 I used:
builder.Services.AddControllersWithViews().AddJsonOptions(opt => opt.JsonSerializerOptions.PropertyNamingPolicy = null);
I am building a scheduling system using fullcalendar for MVC, my get event retrieves from a view for a specific location.
However, my post / save event inserts into the table that the view is made from, containing all locations.
I am getting an error when I try to add the new event to the data connection.
"The field Location must be a string or array type with a maximum length of '1'." string
PropertyName "Location" string
I tried to set the string for the event manually before adding it to the data connection but this isn't working for some reason. Could it be me not declaring the string correctly?
//Actions for Calendar 5
public JsonResult GetEvents5()
{
using (CalgaryNEEntities dc = new CalgaryNEEntities())
{
var events = dc.CalgaryNEEvents.ToList();
return new JsonResult { Data = events, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
}
[HttpPost]
public JsonResult SaveEvent5(EventsAllLocation e)
{
var status = false;
using (InsertEntities dc = new InsertEntities())
{
if (e.EventID > 0)
{
//Update the event
var v = dc.EventsAllLocations.Where(a => a.EventID == e.EventID).FirstOrDefault();
if (v != null)
{
var locationstring = "Calgary NE Kitchens";
v.CompanyName = e.CompanyName;
v.Start = e.Start;
v.End = e.End;
v.KitchenNumber = e.KitchenNumber;
v.Location = locationstring;
}
}
else
{
var locationstring = "Calgary NE Kitchens";
e.Location = locationstring;
dc.EventsAllLocations.Add(e);
}
dc.SaveChanges();
status = true;
}
return new JsonResult { Data = new { status = status } };
}
Here is the EventsAllLocation definition:
public partial class EventsAllLocation
{
public int EventID { get; set; }
public string Location { get; set; }
public string CompanyName { get; set; }
public System.DateTime Start { get; set; }
public Nullable<System.DateTime> End { get; set; }
public string KitchenNumber { get; set; }
}
Any tips or help would be greatly appreciated, thanks!
The answer is staring you in the face !! LOL
"The field Location must be a string or array type with a maximum
length of '1'." string PropertyName "Location" string
Ok, I'm currently working on UIAutomation with nodeJS and I'm using EDGE.js node module. All works fine (wow), but I have an issue with code re-usability.
I have few mostly identical functions that consist from the same code for more than 50%. Of course I want to move this code to a single place, but problem is that this code placed in js comments (EDGE stuff).
How can I reuse my code to avoid repetitions in EDGE.js?
Yeah.. as a last resort I can put everything into one c# "program" and call different c# functions depending on arguments, but probably there is a way to keep several js functions? Thanks!
Here is an example of 2 functions. I want to keep different only "public async Task" part at the bottom of each block. Any ideas?
BTW: Any suggestions about C# code are also welcome! Cause I'm pretty sure, that it's total crap ^^
getWindows: function() {
/*
using System;
using System.Windows;
using System.Windows.Automation;
using System.Threading.Tasks;
using System.Collections.Generic;
public class myRect
{
public int width { get; set; }
public int height { get; set; }
public int top { get; set; }
public int left { get; set; }
public myRect( AutomationElement el ) {
System.Windows.Rect r = (System.Windows.Rect)(
el.GetCurrentPropertyValue(
AutomationElement.BoundingRectangleProperty,
true));
width = (int)r.Width;
height = (int)r.Height;
top = (int)r.Top;
left = (int)r.Left;
}
}
public class Winfo
{
public string name { get; set; }
public string automationId { get; set; }
public int processId { get; set; }
public myRect window { get; set; }
public myRect browser { get; set; }
}
public class Startup {
private Winfo getWinInfo( AutomationElement el ) {
if ( el == null ) return( null );
Winfo winfo = new Winfo {
name = el.Current.Name,
automationId = el.Current.AutomationId,
processId = el.Current.ProcessId,
window = new myRect(el)
};
try {
var tmpWeb = el
.FindFirst( TreeScope.Descendants,
new PropertyCondition(
AutomationElement.ClassNameProperty,
"CefBrowserWindow") )
.FindFirst( TreeScope.Descendants,
new PropertyCondition(
AutomationElement.NameProperty,
"Chrome Legacy Window"));
winfo.browser = new myRect(tmpWeb);
} catch { winfo.browser = null; }
return(winfo);
}
public async Task<object> Invoke(dynamic input) {
var els = AutomationElement.RootElement.FindAll(
TreeScope.Children,
Condition.TrueCondition);
List<Winfo> windowList = new List<Winfo>{};
bool all;
try { all = (bool)input.all; } catch { all = false; };
foreach (AutomationElement el in els) {
Winfo winfo = getWinInfo(el);
if ((winfo!=null) && (all || (winfo.browser!=null))) {
windowList.Add( winfo );
}
}
return(windowList);
}
}
*/
}
And another one
waitWindow: function() {
/*
using System;
using System.Windows;
using System.ComponentModel;
using System.Windows.Automation;
using System.Threading.Tasks;
using System.Threading;
using System.Collections.Generic;
public class myRect {
public int width { get; set; }
public int height { get; set; }
public int top { get; set; }
public int left { get; set; }
public myRect( AutomationElement el ) {
System.Windows.Rect r = (System.Windows.Rect)(
el.GetCurrentPropertyValue(
AutomationElement.BoundingRectangleProperty,
true));
width = (int)r.Width;
height = (int)r.Height;
top = (int)r.Top;
left = (int)r.Left;
}
}
public class Winfo
{
public string name { get; set; }
public string automationId { get; set; }
public int processId { get; set; }
public myRect window { get; set; }
public myRect browser { get; set; }
}
public class Startup {
private static AutoResetEvent waitHandle;
private Winfo getWinInfo( AutomationElement el ) {
if ( el == null ) return( null );
Winfo winfo = new Winfo {
name = el.Current.Name,
automationId = el.Current.AutomationId,
processId = el.Current.ProcessId,
window = new myRect(el)
};
try {
var tmpWeb = el
.FindFirst( TreeScope.Descendants,
new PropertyCondition(
AutomationElement.ClassNameProperty,
"CefBrowserWindow") )
.FindFirst( TreeScope.Descendants,
new PropertyCondition(
AutomationElement.NameProperty,
"Chrome Legacy Window"));
winfo.browser = new myRect(tmpWeb);
} catch { winfo.browser = null; }
return(winfo);
}
public async Task<object> Invoke(dynamic input) {
int t;
try { t = (int)input.timeout; } catch { t = 0; };
string wname;
try { wname = (string)input.name; } catch { wname = ""; };
AutomationElement el = AutomationElement.RootElement.FindFirst(
TreeScope.Children,
new PropertyCondition( AutomationElement.NameProperty, wname ));
if ( el == null ) {
waitHandle = new AutoResetEvent(false);
Automation.AddAutomationEventHandler(
WindowPattern.WindowOpenedEvent,
AutomationElement.RootElement,
TreeScope.Children,
(sender, e) => {
var obj = sender as AutomationElement;
if (obj.Current.Name == wname) {
el = obj;
waitHandle.Set();
}
}
);
waitHandle.WaitOne(t);
Automation.RemoveAllEventHandlers();
}
return( getWinInfo(el) );
}
}
*/
}
};
You can split the reusable C# code into separate multi-line javascript strings, using the same technique that edgejs uses.
Below is a simple example where a function has been broken into two separate variables, Line1 and Line2. You could split your code into multiple functions/variables that contains the re-usable code and then build your code by concatenating the individual bits.
var edge = require('edge');
function getMultilineString(fn){
return (fn).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1];
}
var line1 = getMultilineString(function () {/*
async (input) => {
*/});
var line2 = getMultilineString(function () {/*
return ".NET welcomes " + input.ToString();
}
*/});
//var hello = edge.func(function () {/*
// async (input) => {
// return ".NET welcomes " + input.ToString();
// }
//*/});
var hello = edge.func(line1 + line2);
hello('Node.js', function (error, result) {
if (error) throw error;
console.log(result);
});