public Form LoadingTextAnimation(model.Style style = null) { var loadingDisplay = new controls.LoadingIndicatorText(); lib.styleUtil.style(this, loadingDisplay, style); AddRowToHost(loadingDisplay); return(this); }
public Form Text(string textToDisplay, model.Style style = null) { var label = new TextBlock(); lib.styleUtil.style(this, label, style); label.Text = textToDisplay; AddRowToHost(label); return(this); }
public Form TextBoxFor(string modelFieldName, bool multiline = false, model.Style style = null, Action <string> onTextChanged = null, bool isPassword = false, bool isReadOnly = false, string watermarkText = null) { var tb = new TextBox(); lib.styleUtil.style(this, tb, style); AddBinding <string>(modelFieldName, tb, TextBox.TextProperty, isTwoWayDataBinding: true); // for text changed you do observable because Avalonia hasn't implemented TextChanged for TextBox yet // see: https://github.com/AvaloniaUI/Avalonia/issues/418 tb.GetObservable(TextBox.TextProperty).Subscribe(newTextValue => { onTextChanged?.Invoke(newTextValue); }); tb.IsReadOnly = isReadOnly; if (!string.IsNullOrWhiteSpace(watermarkText)) { tb.Watermark = watermarkText; tb.UseFloatingWatermark = true; } if (isPassword) { tb.PasswordChar = '*'; } if (multiline) { tb.AcceptsReturn = true; tb.AcceptsTab = true; tb.TextWrapping = TextWrapping.Wrap; AddRowToHost(tb, rowAutoHeight: false); } else { AddRowToHost(tb); } return(this); }
public static nac.Forms.Form logViewer(nac.Forms.Form f) { var entries = new ObservableCollection <model.LogEntry>(); model.LogEntry.onNewMessage += (_s, _e) => { // Modifying the entries list has to be thread safe so use Invoke f.InvokeAsync(async() => { entries.Insert(0, _e); }); }; f.Model["logEntriesList"] = entries; f.List <model.LogEntry>("logEntriesList", populateItemRow: (_rF) => { _rF.HorizontalStack(h => { var model = h.Model[nac.Forms.model.SpecialModelKeys.DataContext] as model.LogEntry; var levelStyle = new nac.Forms.model.Style(); if (string.Equals(model.level, "warn", StringComparison.InvariantCulture)) { levelStyle.foregroundColor = Avalonia.Media.Colors.Yellow; } else if (string.Equals(model.level, "info", StringComparison.OrdinalIgnoreCase)) { levelStyle.foregroundColor = Avalonia.Media.Colors.Green; } else if (string.Equals(model.level, "debug", StringComparison.OrdinalIgnoreCase)) { levelStyle.foregroundColor = Avalonia.Media.Colors.Cyan; } else if (string.Equals(model.level, "error", StringComparison.OrdinalIgnoreCase)) { levelStyle.foregroundColor = Avalonia.Media.Colors.Red; } h.TextFor("date") .Text(" - [") .TextFor("level", style: levelStyle) .Text("] - ") .TextFor("message"); }); }); return(f); }
public Form TextFor(string modelFieldName, string defaultValue = null, model.Style style = null) { var label = new TextBlock(); lib.styleUtil.style(this, label, style); AddBinding <string>(modelFieldName, label, TextBlock.TextProperty); if (defaultValue != null) { setModelIfNull(modelFieldName, defaultValue); } AddRowToHost(label); return(this); }
public Form VerticalStack(Action <Form> populateVerticalGroup, model.Style style = null) { var vertGroupForm = new Form(_parentForm: this); populateVerticalGroup(vertGroupForm); var vertGroup = new StackPanel(); lib.styleUtil.style(this, vertGroup, style); var childControls = vertGroupForm.Host.Children.ToList(); foreach (var child in childControls) { vertGroupForm.Host.Children.Remove(child); // get the child out of the form so we can move it to the grid vertGroup.Children.Add(child); } AddRowToHost(vertGroup, rowAutoHeight: false); return(this); }
public Form HorizontalStack(Action <Form> populateHorizontalGroup, model.Style style = null) { var horizontalForm = new Form(_parentForm: this); populateHorizontalGroup(horizontalForm); var horizontalPanel = new StackPanel(); horizontalPanel.Orientation = Orientation.Horizontal; lib.styleUtil.style(this, horizontalPanel, style); var childControls = horizontalForm.Host.Children.ToList(); foreach (var child in childControls) { horizontalForm.Host.Children.Remove(child); // get the child out of the form so we can move it to the grid horizontalPanel.Children.Add(child); } AddRowToHost(horizontalPanel, rowAutoHeight: false); return(this); }
public Form DropDown <T>(string itemSourceModelName, string selectedItemModelName, Action <T> onSelectionChanged = null, Action <Form> populateItemRow = null, model.Style style = null) { var dp = new Avalonia.Controls.ComboBox(); lib.styleUtil.style(this, dp, style); // Just as a safety check, make them init the model first if (!(getModelValue(itemSourceModelName) is IEnumerable <T>)) { throw new Exception($"Model {nameof(itemSourceModelName)} source property specified by name [{itemSourceModelName}] must be a IEnumerable<T>"); } // item source binding AddBinding <IEnumerable>(modelFieldName: itemSourceModelName, control: dp, property: Avalonia.Controls.ComboBox.ItemsProperty, isTwoWayDataBinding: false); // selected item binding AddBinding <object>(modelFieldName: selectedItemModelName, control: dp, property: Avalonia.Controls.ComboBox.SelectedItemProperty, isTwoWayDataBinding: true); if (populateItemRow != null) { dp.ItemTemplate = new FuncDataTemplate <object>((itemModel, nameScope) => { if (itemModel == null) { // how could itemModel be null? Sometimes it is though, so strange var tb = new Avalonia.Controls.TextBlock(); tb.Text = "(null)"; return(tb); } var rowForm = new Form(__app: this.app, _model: new lib.BindableDynamicDictionary()); // this has to have a unique model rowForm.DataContext = itemModel; populateItemRow(rowForm); rowForm.Host.DataContext = itemModel; return(rowForm.Host); }); } dp.SelectionChanged += (_s, _args) => { if (_args.AddedItems.OfType <T>().Any()) { var first = _args.AddedItems.Cast <T>().First(); onSelectionChanged?.Invoke(first); } }; AddRowToHost(dp); return(this); }
/* * For grid info see these two links * https://www.c-sharpcorner.com/Resources/676/how-to-create-a-grid-in-wpf-dynamically.aspx * https://www.wpf-tutorial.com/panels/gridsplitter/ */ public Form VerticalGroup(Action <Form> populateVerticalGroup, bool isSplit = false, model.Style style = null) { var vertGroupForm = new Form(_parentForm: this); populateVerticalGroup(vertGroupForm); Grid vertGroup = new Grid(); lib.styleUtil.style(this, vertGroup, style); var gridCol = new ColumnDefinition(); vertGroup.ColumnDefinitions.Add(gridCol); int rowIndex = 0; int columnIndex = 0; var childControls = vertGroupForm.Host.Children.OfType <Control>().ToList(); foreach (var child in childControls) { vertGroupForm.Host.Children.Remove(child); // get the child out of the form so we can move it to the grid // 1 row for the child control var row = new RowDefinition(); vertGroup.RowDefinitions.Add(row); // set child into the grid Grid.SetRow(child, rowIndex); Grid.SetColumn(child, columnIndex); // if child height is set, then set the row to start that height (If isSplit=true, then you'll be able to resize that row) if (!double.IsNaN(child.Height)) { // size the row to child height row.Height = new Avalonia.Controls.GridLength(child.Height); } vertGroup.Children.Add(child); // 1 row for grid splitter (If not last child) if (isSplit && child != childControls.Last()) { ++rowIndex; // we are on the next row because we are going to add a row definition int splitterHeight = 5; var gridSplitRow = new RowDefinition(); gridSplitRow.Height = new GridLength(splitterHeight); vertGroup.RowDefinitions.Add(gridSplitRow); var gridSplitter = new GridSplitter(); gridSplitter.HorizontalAlignment = global::Avalonia.Layout.HorizontalAlignment.Stretch; gridSplitter.Height = splitterHeight; Grid.SetRow(gridSplitter, rowIndex); Grid.SetColumn(gridSplitter, columnIndex); vertGroup.Children.Add(gridSplitter); } ++rowIndex; // make sure this is last statement } AddRowToHost(vertGroup, rowAutoHeight: false); return(this); }
public Form HorizontalGroup(Action <Form> populateHorizontalGroup, bool isSplit = false, model.Style style = null) { var horizontalGroupForm = new Form(_parentForm: this); populateHorizontalGroup(horizontalGroupForm); // take all the child items of host and put them in a grid with equal space between? Grid horiontalGroup = new Grid(); lib.styleUtil.style(this, horiontalGroup, style); var gridRow = new RowDefinition(); horiontalGroup.RowDefinitions.Add(gridRow); int rowIndex = 0; int columnIndex = 0; var childControls = horizontalGroupForm.Host.Children .OfType <Control>().ToList(); foreach (var child in childControls) { // called ToList above so we can remove this guy from the host children without breaking the foreach horizontalGroupForm.Host.Children.Remove(child); // we have to remove it from the host to be able to add it to the Grid var col = new ColumnDefinition(); horiontalGroup.ColumnDefinitions.Add(col); Grid.SetRow(child, rowIndex); Grid.SetColumn(child, columnIndex); // if child width is set, then start the column at that width if (!double.IsNaN(child.Width)) { col.Width = new Avalonia.Controls.GridLength(child.Width); } horiontalGroup.Children.Add(child); // 1 column for grid splitter (If not last child) if (isSplit && child != childControls.Last()) { ++columnIndex; // incriment because we are going to add a new column below int splitterWidth = 5; var gridSplitColumn = new ColumnDefinition(); gridSplitColumn.Width = new GridLength(splitterWidth); horiontalGroup.ColumnDefinitions.Add(gridSplitColumn); var gridSplitter = new GridSplitter(); gridSplitter.HorizontalAlignment = global::Avalonia.Layout.HorizontalAlignment.Stretch; gridSplitter.Width = splitterWidth; Grid.SetRow(gridSplitter, rowIndex); Grid.SetColumn(gridSplitter, columnIndex); horiontalGroup.Children.Add(gridSplitter); } ++columnIndex; // last statement } AddRowToHost(horiontalGroup); return(this); }