I've made a void method that adds pages to my tabbed page. In this, it creates entry boxes but they are unnamed. After the person has filled in the entry boxes I want to create a report from it. How do I access the entry boxes for the information?
This is the part that adds the new entry:
grid.Children.Add(new Entry
{
AutomationId = "weerstand" + lusnummer.ToString(),
Text = "[weerstand]",
TextColor = Color.Black,
FontSize = 18,
}, 2, rownumber);
//button and bottom
Button Reportbutton = new Button
{
Text = "Report",
BackgroundColor = Color.FromHex("#093d80"),
Padding = 24,
TextColor = Color.White,
FontSize = 36,
TextTransform = TextTransform.None,
};
Reportbutton.Clicked += GenerateReport_OnClicked;
grid2.Children.Add(
Reportbutton, 0, 0);
//make page
StackLayout stacklayout1 = new StackLayout()
{
Children =
{
grid,
grid2
}
};
ScrollView pagescroll = new ScrollView()
{
Content = stacklayout1
};
ContentPage page = new ContentPage()
{
Title = "LDTB-" + number.ToString(),
Content = pagescroll
};
Children.Add(page);
}
private async void GenerateReport_OnClicked(object sender, EventArgs e)
{
//yes or no
bool answer = await DisplayAlert("Rapport", "Wilt u het rapport maken", "Yes", "No");
//Generate report
if (answer == true){
//WHAT GOES HERE TO ACCESS THE Entry?
}
}
}
You can traverse your Grid and access the value of entries in it.
You can refer the following code:
var children = grid.Children;
foreach(View child in children){
if (child is Entry) {
string value = ((Entry)child).Text;
System.Diagnostics.Debug.WriteLine("one value is = " + value);
}
}
Related
i am using code behind visual state managers to give selected labels a background color, but this doesnt work, any idea why?
var frameStackLayoutX = new StackLayout
{
Spacing = 5
};
var vsg = new VisualStateGroup() { Name = "CommonStates" };
var vs = new VisualState { Name = "Selected" };
vs.Setters.Add(new Setter
{
TargetName = "Selected",
Property = Label.BackgroundColorProperty,
Value = Colors.Red
});
vsg.States.Add(vs);
VisualStateManager.GetVisualStateGroups(frameStackLayoutX).Add(vsg);
var LabelName = new Label();
LabelName.Text = "Jhon Doe"
LabelName .WidthRequest = 100;
LabelName .Padding = new Thickness(10, 0, 0, 0);
frameStackLayoutX.Add(LabelName );
return frameStackLayoutX;
This is inside a grid, wherei use _lines.SelectedItem = pressedItem; to make sure that I can click on my label.
I just read and applied it to the dynamic object on the panel for the container, the label for the title, the textbox for the contents.
but here I can't save it when I fill in the data in the textbox.
this is my deserialize xml code:
string Location= Path.Combine("D:\\Data\\Code.xml");
XmlDocument doc = new XmlDocument();
doc.Load(lokasiString);
foreach (XmlNode node in doc.DocumentElement)
{
string name = node.Attributes[0].InnerXml;
string value = node.InnerText;
// create panel
Panel panel = new Panel();
panel.Name = "panelImages";
panel.Size = new Size((int)(this.Width*0.9), 30);
panel.Dock = DockStyle.Top;
panel.BorderStyle = BorderStyle.FixedSingle;
Label l = new Label();
l.Text = name;
l.Font = new Font("Serif", 12, FontStyle.Bold);
l.ForeColor = Color.Black;
l.Size = new Size((int)(this.Width * 0.2), 30);
l.Dock = DockStyle.Left;
TextBox tb = new TextBox();
tb.Text = value;
tb.Font = new Font("Serif", 12, FontStyle.Bold);
tb.ForeColor = Color.Black;
tb.Size = new Size((int)(this.Width * 0.9), 30);
tb.Dock = DockStyle.Left;
panel.Controls.Add(tb);
panel.Controls.Add(lt);
panel.Controls.Add(l);
flowLayoutPanel1.Controls.Add(panel);
}
and this my Xml Code:
<resources>
<string name="name">Tap Crush</string>
<string name="mode">Slow</string>
<string name="score">12345</string>
</resources>
I have no prior knowledge of parsing Xml with C#.
Define model classes and use databinding to edit the model, then you can break the problem to the following pieces:
Defining a Model class containing a List<Resource> and each Resource having Title and Content.
Write some logic to load model from xml or save model to xml.
Write a piece of code to arrange UI and setup UI controls to use databinding to your mode.
Then you can easily Load data from xml, edit in the UI and Save data to xml.
Model classes
You can model classes like this:
public class Model
{
public List<Resource> Resources { get; set; }
}
public class Resource
{
public string Title { get; set; }
public string Content { get; set; }
}
Setting up UI
There are different approaches to dynamically show a collection of controls in a form. Here I'll show how you can do that using a DataGridView as well as a TableLayoutPanel:
DataGridView
TableLayoutPanel
Create DataGridView
var dg = new DataGridView();
dg.Dock = DockStyle.Fill;
dg.BorderStyle = BorderStyle.None;
dg.GridColor = Color.Black;
dg.AutoGenerateColumns = true;
dg.EditMode = DataGridViewEditMode.EditOnEnter;
dg.DataSource = model.Resources;
dg.DataBindingComplete += (o, a) =>
{
dg.RowHeadersVisible = dg.ColumnHeadersVisible = false;
dg.AllowUserToResizeColumns = false;
dg.AllowUserToResizeRows = false;
dg.BackgroundColor = SystemColors.Control;
dg.Columns[0].ReadOnly = true;
dg.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
dg.Columns[0].DefaultCellStyle.ForeColor = Color.Black;
dg.Columns[0].DefaultCellStyle.BackColor = SystemColors.Control;
dg.Columns[0].DefaultCellStyle.SelectionForeColor = Color.Black;
dg.Columns[0].DefaultCellStyle.SelectionBackColor = SystemColors.Control;
dg.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
};
this.Controls.Add(dg);
Create TableLayoutPanel
var tlp = new TableLayoutPanel() { ColumnCount = 2, AutoSize = true };
tlp.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
tlp.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
tlp.SuspendLayout();
foreach (var resource in model.Resources)
{
tlp.RowStyles.Add(new RowStyle(SizeType.AutoSize));
var lbl = new Label() { AutoSize = true, Margin = new Padding(4) };
lbl.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
lbl.DataBindings.Add(new Binding(nameof(Label.Text), resource, nameof(Resource.Title)));
var txt = new TextBox();
txt.DataBindings.Add(new Binding(nameof(TextBox.Text), resource, nameof(Resource.Content)));
txt.Dock = DockStyle.Fill;
tlp.Controls.AddRange(new Control[] { lbl, txt });
}
tlp.ResumeLayout();
this.Controls.Add(tlp);
Load and Save Model
You can create a class like this:
public class ModelFactory
{
public Model FromXmlString(string xml)
{
return new Model()
{
Resources = XElement.Parse(xml).Elements()
.Select(x => ResourceFromXElement(x)).ToList()
};
}
public string ToXmlString(Model model)
{
return new XElement("resources",
model.Resources.Select(x => ResourceToXElement(x)).ToArray())
.ToString();
}
private Resource ResourceFromXElement(XElement element)
{
return new Resource()
{
Title = element.Attribute("name").Value,
Content = element.Value
};
}
private XElement ResourceToXElement(Resource resource)
{
return new XElement("string",
new XAttribute("name", resource.Title),
resource.Content);
}
}
Then easily load and save model:
Model model;
ModelFactory modelFactory = new ModelFactory();
private void loadButton_Click(object sender, EventArgs e)
{
var xml = #"
<resources>
<string name=""name"">Tap Crush</string>
<string name=""mode"">Slow</string>
<string name=""score"">12345</string>
</resources>";
//Load model from xml
model = modelFactory.FromXmlString(xml);
//Setup UI
}
private void saveButton_Click(object sender, EventArgs e)
{
//Save model to xml
var xml = modelFactory.ToXmlString(model);
MessageBox.Show(xml);
}
I have a Form with one Button. When I click the Button, then programmatically create a Panel with one CheckBox and a TextBox; but for the TextBox the Visible is false.
If I checked the CheckBox, I want to change my TextBox to Visible = true.
Any body can help me?
public void CreateSlide(string name, string title, string desc)
{
var PanelOrder = new Panel()
{
Name = name,
Size = new Size(395, 33),
BorderStyle = BorderStyle.FixedSingle,
Location = new Point(203, 157)
};
var ckOrder = new CheckBox()
{
Name = name,
Text = "Order",
Size = new Size(102, 21),
Location = new Point(3, 5),
FlatStyle = FlatStyle.Flat,
Font = new Font("Segoe UI", 10, FontStyle.Bold)
};
ckOrder.CheckedChanged += new EventHandler(this.ckBoxOrder_CheckedChanged);
var TxtQty = new TextBox
{
Name = name,
Text = "1",
Visible = false,
BorderStyle = BorderStyle.FixedSingle,
Size = new Size(100, 25),
Location = new Point(290, 3)
};
PanelOrder.Controls.Add(ckOrder);
PanelOrder.Controls.Add(TxtQty);
}
Relevant event handler is
private void ckBoxOrder_CheckedChanged(object sender, EventArgs e)
{
if (((CheckBox)sender).Checked == true)
{
// ??? TxtQty.Visible = true; // <- doesn't compile
}
else
{
// ??? TxtQty.Visible = false; // <- doesn't compile
}
}
You can try using lambda in order to keep all the relevant code within CreateSlide:
public void CreateSlide(string name, string title, string desc) {
var PanelOrder = new Panel() {
Name = name,
Size = new Size(395, 33),
BorderStyle = BorderStyle.FixedSingle,
Location = new Point(203, 157),
Parent = this // <- Put PanelOrder panel on the form
};
var ckOrder = new CheckBox() {
Name = name,
Text = "Order",
Size = new Size(102, 21),
Location = new Point(3, 5),
FlatStyle = FlatStyle.Flat,
Font = new Font("Segoe UI", 10, FontStyle.Bold),
Parent = PanelOrder // <- Put ckOrder on the PanelOrder panel
};
var TxtQty = new TextBox() {
Name = name,
Text = "1",
Visible = false,
BorderStyle = BorderStyle.FixedSingle,
Size = new Size(100, 25),
Location = new Point(290, 3),
Parent = PanelOrder // <- Put TxtQty on the PanelOrder panel
};
// lambda function
ckOrder.CheckedChanged += (s, e) => {
TxtQty.Visible = ckOrder.Checked;
};
}
you need to declare a variable (reference) for the textbox outside the scope of the function that creates it, then you can set it to visible true/false. alternatively (slower) you can enumerate all controls in the form (or the panel), find your text box and set it to visible true/false.
I've been at this for a while now and cannot seem to figure out how to get the Eto.Forms TreeGridView Control to properly render. I'm trying to just add a few GridViewItem's at the moment and I just get a small gray bar at the top:
Here is my code:
List<ITreeGridItem> treeGridItems = new List<ITreeGridItem>();
foreach (var contentType in contentTypes)
{
treeGridItems.Add(new TreeGridItem(contentType.Name));
}
Content = new DocumentPage(new TreeGridView
{
DataStore = new TreeGridItemCollection(treeGridItems)
}, new Padding(20));
I'm not even really sure where to start, I just want to get a tree with text to show for each node at the moment and I can't even do that.
After a bit of trial and error I figured out how to use the tree view:
var treeGridView = new TreeGridView
{
BackgroundColor = Colors.White
};
treeGridView.Columns.Add(new GridColumn
{
HeaderText = "Content Type",
DataCell = new TextBoxCell(0)
});
treeGridView.Columns.Add(new GridColumn
{
HeaderText = "Create",
DataCell = new CustomCell
{
CreateCell = r =>
{
TreeGridItem item = r.Item as TreeGridItem;
ContentTypeTag tag = (ContentTypeTag)item.Tag;
var contentType = _siteManager.CurrentSite.ContentTypes.First(x => x.Name.Equals(tag.ClassName));
void Click(object btnSender, EventArgs btnArgs)
{
//Your Event
}
var button = new LinkButton
{
Style = "primary-link-btn",
Text = $"Create {contentType.Name.ToSentenceCase()}",
Command = new Command(Click)
};
return button;
}
}
});
treeGridView.Columns.Add(new GridColumn
{
HeaderText = "Show All",
DataCell = new CustomCell
{
CreateCell = r =>
{
TreeGridItem item = r.Item as TreeGridItem;
ContentTypeTag tag = (ContentTypeTag)item.Tag;
var contentType = _siteManager.CurrentSite.ContentTypes.First(x => x.Name.Equals(tag.ClassName));
void Click(object btnSender, EventArgs btnArgs)
{
//Your Event
}
var button = new LinkButton
{
Style = "primary-link-btn",
Text = $"Show All {contentType.Name.ToSentenceCase()}",
Command = new Command(Click)
};
return button;
}
}
});
var treeGridItemCollection = new TreeGridItemCollection();
foreach (var contentType in _siteManager.CurrentSite.ContentTypes)
{
var item = new TreeGridItem
{
Values = new string[] { contentType.Name.ToSentenceCase(), "Create", "Show All" },
Tag = new ContentTypeTag
{
ClassName = contentType.Name
}
};
treeGridItemCollection.Add(item);
}
treeGridView.DataStore = treeGridItemCollection;
You create the header columns to start and then create a TreeGridItemCollection and set the datastore to that. The values for each column of the row is set in a string array to the Values property of the TreeGridItem.
Hello this is the first time using Xamarin. What I am trying to do is modify this application to use ListView, but first I would like to learn how to get a value from a stepper and print it to the label.
I know movieamount sends the value selected from the stepper and sends it to the totalLabel text, but I can't seem to figure out how to send it to the label with 0 already and have it change values when selected. It does return the correct amount selected but never prints to the screen.
public static string movieamount;
public static string pickmovie;
public static string paymentSelected;
public static string dateSelected;
public static string timeSelected;
public static string totalLabel;
public MainPage()
{
Picker picker = new Picker
{
Title = "Movies",
VerticalOptions = LayoutOptions.CenterAndExpand
};
var options = new List<string> { "Kill Bill", "Matrix", "Zombieland", "The Dark Knight", "Terminator", "Apocalypse Now", "Resouvoir dogs", "Horrible Bosses", "The Breakup", "Wedding Crashers", };
picker.SelectedIndexChanged += (sender, e) =>
{
pickmovie = picker.Items[picker.SelectedIndex];
};
foreach (string optionName in options) picker.Items.Add(optionName);
//listView.ItemTapped += async (sender, e) => { await DisplayAlert("Tapped", e.Item.ToString() + " was selected.", "OK"); ((ListView)sender).SelectedItem = null; };
//this.Content = listView;
Label valuelabel = new Label
{
Text = "0",
FontAttributes = FontAttributes.Bold,
FontSize = 30,
HorizontalOptions = LayoutOptions.Center
};
Stepper stepper = new Stepper
{
Minimum = 0,
Maximum = 10,
Increment = 1,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.CenterAndExpand
};
stepper.ValueChanged += (sender, e)=>
{
movieamount = stepper.Value.ToString();
};
Picker payment = new Picker
{
Title = "Payment Method",
VerticalOptions = LayoutOptions.CenterAndExpand
};
var options1 = new List<string> {"Visa", "MasterCard", "AmericanExpress", "Free",};
foreach (string optionName in options1) payment.Items.Add(optionName);
payment.SelectedIndexChanged += (sender, e) =>
{
paymentSelected = payment.Items[payment.SelectedIndex];
};
//TimePicker was here
Label totalLabel = new Label
{
HorizontalOptions = LayoutOptions.CenterAndExpand,
FontSize = 40,
FontAttributes = FontAttributes.Bold | FontAttributes.Italic
};
DatePicker datePicker = new DatePicker
{
Format = "D",
VerticalOptions = LayoutOptions.CenterAndExpand,
};
//---Handle Inline---
datePicker.DateSelected += (object sender, DateChangedEventArgs e) =>
{
//eventValue.Text = e.NewDate.ToString();
dateSelected = e.NewDate.ToString();
};
TimePicker timePicker = new TimePicker
{
Format = "T",
VerticalOptions = LayoutOptions.CenterAndExpand
};
// set inline handler
timePicker.PropertyChanged += (sender, e) =>
{
if (e.PropertyName == TimePicker.TimeProperty.PropertyName)
{
timeSelected = timePicker.Time.ToString();
};
};
Button button = new Button
{
Text = "Submit",
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Button)),
HorizontalOptions = LayoutOptions.CenterAndExpand,
VerticalOptions = LayoutOptions.Fill
};
button.Clicked += (sender, args) =>
{
totalLabel.Text = "You have ordered " + movieamount + " " +
pickmovie + " \n You will be paying with " + paymentSelected + " " +
"Your delivery will be delivered at " + dateSelected + " " + timeSelected;
};
StackLayout stackLayout = new StackLayout
{
Children =
{
picker,
payment,
valuelabel,
stepper,
datePicker,
totalLabel,
timePicker,
button,
}
};
BackgroundColor = Color.Yellow;
this.Content = stackLayout;
}
}
}
This is one way to approach it - a "brute force" method. Optionally, you could use MVVM and databinding, but that is more advanced and may be more than you want to bite off at this point
// declare this method outside of the constructor
private void UpdateLabel() {
totalLabel.Text = "You have ordered " + movieamount + " " +
pickmovie + " \n You will be paying with " + paymentSelected + " " +
"Your delivery will be delivered at " + dateSelected + " " +
timeSelected;
}
// then modify these existing handlers to call UpdateLabel
stepper.ValueChanged += (sender, e)=>
{
movieamount = stepper.Value.ToString();
UpdateLabel();
};
// you should also call UpdateLabel in the other handlers that update values
button.Clicked += (sender, args) =>
{
UpdateLabel();
};
ok. I will try that and expirement with it. I was able to find my answer with this line of code. That I entered right after stepper.ValueChanged += (sender, e)=>
valuelabel.Text = String.Format(" {0:F1}", e.NewValue);