Open source multi-platform UI framework. Create your apps once on PCL and have your UI generated on runtime for ASP.NET, Windows Forms, WPF, Linux (Mono + WinForms), Mac OS (Mono + WinForms and Xamarin.Mac), iOS, Android, Windows Phone (via Xamarin.Forms) and Windows Universal Platform.
PM> Install-Package OKHOSTING.UI
PM> Install-Package OKHOSTING.UI.CSS
PM> Install-Package OKHOSTING.UI.Net4.WebForms
PM> Install-Package OKHOSTING.UI.Net4.WinForms
PM> Install-Package OKHOSTING.UI.Net4.WPF
PM> Install-Package OKHOSTING.UI.UWP
PM> Install-Package OKHOSTING.UI.Xamarin.Forms
- Download OKHOSTING.UI on NuGet
- Download OKHOSTING.UI.CSS on NuGet
- Download OKHOSTING.UI.Net4.WebForms on NuGet
- Download OKHOSTING.UI.Net4.WinForms on NuGet
- Download OKHOSTING.UI.Net4.WPF on NuGet
- Download OKHOSTING.UI.UWP on NuGet
- Download OKHOSTING.UI.Xamarin.Forms on NuGet
- Create your apps in PCL and run them everywhere, truly multi-platform (web included)
- The UI is defined from code (XAML designer on the way)
- 100% native controls are used in all platforms
- You have the "common" UI api surface among all platforms by default, ands it's easily extendible
- Supports click, doble click and, for user input controls, value changed events
- Using OKHOSTING.UI.CSS you can use CSS files to define the styles of your controls (thanks to AngleSharp)
- Autocomplete
- Button
- Calendar
- CheckBox
- HyperLink
- Image
- Label
- ListPicker (equivalent to a DropDownList)
- PasswordTextBox
- TextArea
- TextBox
- Create forms for user data input/output
- Create form fields for string, int, decimal, date, enum, bool, xml or any custom type you need
- Create forms to execute a method
This examples are taken from https://github.com/okhosting/OKHOSTING.UI/tree/master/test
The platform uses native controls in all platforms, therefore all apps work with great performance and compatibility
A Page is an interface that is implemented as:
- A System.Web.UI.Page in ASP.NET
- A System.Windows.Window in Windows Forms
- A System.Windows.Window in WPF
- A Windows.UI.Xaml.Controls.Page in UWP
- A Xamarin.Forms.ContentPage in Xamarin Forms
You can set page properties like this:
Platform.Current.Page.Title = "Choose one control to test";
Platform.Current.Page.Content = grid;
The framework uses classes called "Controllers", which work very much like an MVC controller. To work with the framework, you need to inherit from Controller class and override (at least) the Start() method. For example take a look a this IndexController:
public class IndexController: Controller
{
public override void Start()
{
base.Start();
IGrid grid = Platform.Current.Create<IGrid>();
grid.ColumnCount = 1;
grid.RowCount = 20;
ILabelButton lblAutocomplete = Platform.Current.Create<ILabelButton>();
lblAutocomplete.Text = "Autocomplete";
lblAutocomplete.Click += (object sender, EventArgs e) => new AutocompleteController().Start();
grid.SetContent(0, 0, lblAutocomplete);
ILabelButton lblLabel = Platform.Current.Create<ILabelButton>();
lblLabel.Text = "Label";
lblLabel.Click += (object sender, EventArgs e) => new LabelController().Start();
grid.SetContent(1, 0, lblLabel);
ILabelButton lblLabelButton = Platform.Current.Create<ILabelButton>();
lblLabelButton.Text = "Label Button";
lblLabelButton.Click += (object sender, EventArgs e) => new LabelButtonController().Start();
grid.SetContent(2, 0, lblLabelButton);
ILabelButton lblButton = Platform.Current.Create<ILabelButton>();
lblButton.Text = "Button";
lblButton.Click += (object sender, EventArgs e) => new ButtonController().Start();
grid.SetContent(3, 0, lblButton);
ILabelButton lblHyperLink = Platform.Current.Create<ILabelButton>();
lblHyperLink.Text = "HyperLink";
//lblHyperLink.Click += (object sender, EventArgs e) => new HyperLinkController().Start();
grid.SetContent(4, 0, lblHyperLink);
ILabelButton lblCheckbox = Platform.Current.Create<ILabelButton>();
lblCheckbox.Text = "Checkbox";
lblCheckbox.Click += (object sender, EventArgs e) => new CheckboxController().Start();
grid.SetContent(5, 0, lblCheckbox);
ILabelButton lblImage = Platform.Current.Create<ILabelButton>();
lblImage.Text = "Image";
lblImage.Click += (object sender, EventArgs e) => new ImageController().Start();
grid.SetContent(6, 0, lblImage);
ILabelButton lblImageButton = Platform.Current.Create<ILabelButton>();
lblImageButton.Text = "ImageButton";
lblImageButton.Click += (object sender, EventArgs e) => new ImageButtonController().Start();
grid.SetContent(7, 0, lblImageButton);
Platform.Current.Page.Title = "Choose one control to test";
Platform.Current.Page.Content = grid;
}
}
As you can see, the IndexController creates a grid, and then populates the grid with many LabelButtons. Each button has a different Text and click events, and when you click on the LableButton with text "Button", that triggers an event that leads you to another controller named ButonController.
Also you can set the Title of the Page, and of course, the actual content of the Page.
When you dont finish a controller, and call another controller to Start(), the new controller will "take control" of the app (more acuratelly, your Page) and will manipulate the UI. When you finish a controller, the app returns control to the previous controller in the stack, and all UI state is maitained in this cycle.
public class ButtonController: Controller
{
IButton cmdShow;
ILabel lbltext;
public override void Start()
{
base.Start();
IStack stack = Platform.Current.Create<IStack>();
cmdShow = Platform.Current.Create<IButton>();
cmdShow.Text = "Show/Hide";
cmdShow.Click += CmdShow_Click;
cmdShow.BackgroundColor = new Color(1, 255, 0, 0);
cmdShow.FontColor = new Color(1, 255, 255, 255);
stack.Children.Add(cmdShow);
lbltext = Platform.Current.Create<ILabel>();
lbltext.Text = "I'm visible, i want an ice-cream";
lbltext.Visible = false;
stack.Children.Add(lbltext);
IButton cmdClose = Platform.Current.Create<IButton>();
cmdClose.Text = "Close";
cmdClose.Click += CmdClose_Click;
stack.Children.Add(cmdClose);
Platform.Current.Page.Title = "Test label";
Platform.Current.Page.Content = stack;
}
private void CmdShow_Click(object sender, EventArgs e)
{
if (lbltext.Visible == true)
{
lbltext.Visible = false;
}
else
{
lbltext.Visible = true;
}
}
private void CmdClose_Click(object sender, EventArgs e)
{
this.Finish();
}
}
public class CheckboxController: Controller
{
ICheckBox cbxColor;
ILabel lblLabel;
public override void Start()
{
base.Start();
IStack stack = Platform.Current.Create<IStack>();
lblLabel = Platform.Current.Create<ILabel>();
lblLabel.Text = "This is a label";
lblLabel.Height = 30;
stack.Children.Add(lblLabel);
cbxColor = Platform.Current.Create<ICheckBox>();
cbxColor.Name = "color";
cbxColor.Value = true;
stack.Children.Add(cbxColor);
IButton cmdChange = Platform.Current.Create<IButton>();
cmdChange.Text = "Change";
cmdChange.Click += CmdChange_Click;
stack.Children.Add(cmdChange);
IButton cmdClose = Platform.Current.Create<IButton>();
cmdClose.Text = "Close";
cmdClose.Click += CmdClose_Click;
stack.Children.Add(cmdClose);
Platform.Current.Page.Title = "Test label";
Platform.Current.Page.Content = stack;
}
private void CmdChange_Click(object sender, EventArgs e)
{
if(cbxColor.Value == true)
{
lblLabel.FontColor = new Color(1, 255, 0, 0);
}
else
{
lblLabel.FontColor = new Color(1, 0, 0, 0);
}
}
private void CmdClose_Click(object sender, EventArgs e)
{
this.Finish();
}
}
public class HyperLinkController: Controller
{
public override void Start()
{
base.Start();
IStack stack = Platform.Current.Create<IStack>();
ILabel lblLabel = Platform.Current.Create<ILabel>();
lblLabel.Text = "Visit";
lblLabel.Height = 30;
stack.Children.Add(lblLabel);
IHyperLink hplUrl = Platform.Current.Create<IHyperLink>();
hplUrl.Text = "https://www.okhosting.com";
hplUrl.Uri = new Uri("https://www.okhosting.com");
hplUrl.Name = "okhosting.com";
stack.Children.Add(hplUrl);
IButton cmdClose = Platform.Current.Create<IButton>();
cmdClose.Text = "Close";
cmdClose.Click += CmdClose_Click;
stack.Children.Add(cmdClose);
Platform.Current.Page.Title = "Test label";
Platform.Current.Page.Content = stack;
}
private void CmdClose_Click(object sender, EventArgs e)
{
this.Finish();
}
}
public class ImageController: Controller
{
public override void Start()
{
base.Start();
IStack stack = Platform.Current.Create<IStack>();
ILabel lblLabel = Platform.Current.Create<ILabel>();
lblLabel.Text = "View an image from Url";
lblLabel.Height = 30;
stack.Children.Add(lblLabel);
IImage imgPicture = Platform.Current.Create<IImage>();
imgPicture.LoadFromUrl(new Uri("https://www.patycantu.com/wp-content/uploads/2014/07/91.jpg"));
imgPicture.Height = 250;
imgPicture.Width = 600;
stack.Children.Add(imgPicture);
IButton cmdClose = Platform.Current.Create<IButton>();
cmdClose.Text = "Close";
cmdClose.Click += CmdClose_Click;
stack.Children.Add(cmdClose);
Platform.Current.Page.Title = "Test label";
Platform.Current.Page.Content = stack;
}
private void CmdClose_Click(object sender, EventArgs e)
{
this.Finish();
}
}
The proyect is in beta state, feel free to try it and run it for test projects for now. All platforms are running now, some controls dont have all features fully supported (design stuff mostly) in some platforms. All the core logic on the framework is running very well and generally stable.
So far tested on ASP.NET Web Forms, Windows Forms, WPF, Mac OS X, iOS and Android.
Published under the very permissive MIT License
Checkout
- https://github.com/okhosting/OKHOSTING.ORM
- https://github.com/okhosting/OKHOSTING.ORM/tree/master/src/PCL/OKHOSTING.ORM.UI
To integrate a fully working and also multi platform ORM and integrated CRUD UI generation on top of OKHOSTING.UI.
So you could create full multiplatform apps for CRUD operations very fast. And them add some customization, all from one code base in PCL libraries.