I have an object model class ( desarlise json to object model ) , i want to use binding to attach the object model to the UI using xamarin forms.
P.S not natively nor XAML but through code.
Have search the internet but its getting more and more confusing
Any help will be anxiously helpful
Thanks
Your question is a bit unclear, but here's an example of data binding for Xamarin.Forms in code.
//INPC implementation removed in this sample
public class PersonViewModel
{
public string FirstName {get;set;}
public string LastName {get;set;}
}
var person = new PersonViewModel {
FirstName = "John",
LastName = "Doe",
};
var first = new Label ();
first.SetBinding (Label.TextProperty, "FirstName");
var label = new Label ();
label.SetBinding (Label.TextProperty, "LastName");
var personView = new StackLayout {
Orientation = StackOrientation.Horizontal,
Children = {
first,
last
}
};
personView.BindingContext = person;
Related
I have a DataGridView that I am trying to populate as follows:
List<pupil> listOfUsers = new List<pupil>(); // Create a new list
listOfUsers = pupil.LoadPupilDetails(); // Populate the list with a list of all users
dgvPupil.DataSource = listOfUsers;
The code works in another project of mine and I followed the same process but it won't appear. The list does return users from a text file. I have also break pointed and can confirm the dgvPupil.DataSource shows this data but it simply won't show on the rendered form.
Initailly, I had this code in the form load event, but I then tried applying it through a manual button click event to no avail.
I would really appreciate some help with this.
Sorry for the delay and thank you so much for trying to help.
I usually use encapsulation but for this program, I was aiming for simplicity and was using public properties. So I learned that my class required the properties to have getters and setters so that backing fields would be created at run time. This allowed the data to protrude through to the DGV!
See if the simple code sample helps using mocked data. What is needed is to see code that you have as your current code does not really provide enough details.
Note 1 I created the columns for the DataGridView in the designer, set header text and DataPropertyName to match up with each property in the Pupil class.
Note 2 Learn to use a BindingSource.
I would recommend creating a new form devoid of anything other than what is needed to diagnose the current issue.
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace PupilsProject
{
public partial class Form1 : Form
{
private readonly BindingSource _bindingSource = new BindingSource();
public Form1()
{
InitializeComponent();
dgvPupil.AutoGenerateColumns = false;
_bindingSource.DataSource = Mocked.Pupils();
dgvPupil.DataSource = _bindingSource;
foreach (DataGridViewColumn column in dgvPupil.Columns)
{
Console.WriteLine(
$"{column.Name}, {column.DataPropertyName}, {column.DefaultCellStyle.Format}");
}
}
}
class Pupil
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
}
class Mocked
{
public static List<Pupil> Pupils() =>
new List<Pupil>
{
new Pupil()
{
FirstName = "Jim",
LastName = "Adams",
BirthDate = new DateTime(1990, 1, 2)
},
new Pupil()
{
FirstName = "Mary",
LastName = "Jones",
BirthDate = new DateTime(1980, 11, 4)
},
new Pupil()
{
FirstName = "Mile",
LastName = "White",
BirthDate = new DateTime(1970,10,9)
}
};
}
}
Output for each DataGridView column
FirstNameColumn, FirstName,
LastNameColumn, LastName,
BirthDateColumn, BirthDate, d
Sorry for this basic question
I have a data model :
class data_test
{
public string textdata { get; set; }
public bool booldata { get; set; }
public bool checkdata { get; set; }
public data_opt enumdata { get; set; }
}
Here's Enum :
enum data_opt
{
managed = 1,
unmanaged = 2 ,
mixed = 3
}
Then I create a data model :
var n_Data = new data_test()
{ textdata = "test data",
booldata = false,
checkdata = true ,
enumdata = data_opt.mixed
};
And I create a text box from code behind :
var text_box = new TextBox();
Now I want to bind text_box.Text property to n_Data.textdata from code behind
The same way DataGrid works , two-way connection with real-time update.
I found some pages :
Binding String Property in Code-Behind TextBlock
WPF Data Binding to a string property
Binding string property to object
Unfortunately , none of them worked for me , Here's my code to bind:
Binding binding = new Binding();
binding.Path = new PropertyPath("textdata");
binding.Source = n_Data;
text_box.SetBinding(TextBlock.TextProperty, binding);
Also I tried this :
Binding binding = new Binding();
binding.Path = new PropertyPath("textdata");
binding.Source = n_Data;
BindingOperations.SetBinding(text_box, TextBlock.TextProperty, binding);
Both of them don't work , What am I doing wrong ?
Since your target is a TextBox, you can't use TextBlock.TextProperty as property to bind. You need to use TextBox.TextProperty:
text_box.SetBinding(TextBox.TextProperty, binding);
I have been using BindingLists to show object data for Threads running in my application.
This has always worked great.
Now I want to show my own object's properties in a DataGridView, the binding of the empty BindingList succeeds without trouble.
However when adding elements to the list, I get an exception stating there must be columns in the DataGridView
The code which works:
BindingList<Thread> threads = new BindingList<Thread>();
dgThreadStates.DataSource = new BindingSource() { DataSource = threads }; //DataGridView
Thread t = new Thread(new ParameterizedThreadStart(handler.handleEntries));
threads.Add(t);
This however does not seem to work:
public class Customer
{
public System.Guid GUID;
public string FirstName;
public string MiddleName;
public string LastName;
public string Postcode;
public string HouseNo;
public string StreetName;
public string City;
}
The Method:
BindingList<Customer> savedCustomers = new BindingList<Customer>();
dgvCustomers.DataSource = new BindingSource() { DataSource = savedCustomers }; //DataGridView
savedCustomers.Add(new Customer());
I'll get this exception:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll. Additional Information: No row can be added to a DataGridView control that does not have columns. Columns must be added first.
Databinding works with properties not fields. The DataGridView won't find Properties for generating columns (i assume you use autocreatecolumns in your grid) in your class and refuses to work without any columns.
So you need to replace your fields with (atleast automatic) properties.
public class Customer
{
public System.Guid GUID { get; set; }
// etc.
}
Here is possible solution
var list = new List<users>()
{
new Person { Name = "Robin", },
new Person { Name = "Cleef", },
};
var bindingList = new BindingList<users>(list);
var source = new BindingSource(bindingList, null);
grid.DataSource = source;
I have a C# WPF application that has a form with two fields. Every time the form is submitted, I want to get the values and use the Instructor class to add the new item to a list. Then, I want to loop through the list and display the items in the ListView element. I realize I can do this without the class, but having the class is a requirement for my school assignment.
Here is my Main Window class:
public partial class MainWindow : Window
{
private List<Instructor> instList;
public MainWindow()
{
InitializeComponent();
List<Instructor> instList = new List<Instructor> { };
}
private void btnCreateInstructor_Click(object sender, RoutedEventArgs e)
{
spCreateInstructor.Visibility = (spCreateInstructor.Visibility == Visibility.Hidden) ? Visibility.Visible : Visibility.Hidden;
}
private void btnInstructorSubmit_Click(object sender, RoutedEventArgs e)
{
instList.Add(new Instructor { firstName = txtInstructorFirstName.Text, lastName = txtInstructorLastName.Text });
foreach (var inst in instList)
{
lvInstructorList.Items.Add("{0} {1}", inst.firstName, inst.lastName);
//Error occurs on the line above.
}
}
}
This is the instructor class:
class Instructor
{
public string firstName { set; get; }
public string lastName { set; get; }
}
My problem is that I get an error saying No overload for method Add takes 3 arguments What am I doing wrong? I have indicated where the error occurs with a comment in the code.
Try replacing this line:
lvInstructorList.Items.Add("{0} {1}", inst.firstName, inst.lastName);
with this one
lvInstructorList.Items.Add(new Instructor { firstName = inst.firstName, lastName = inst.lastName });
It is similar to how you added to the instList.
Edit
After realizing lvInstructorList is a ListView xaml element, this should work:
var listViewItem = new ListViewItem(new Instructor { firstName = inst.firstName, lastName = inst.lastName });
lvInstructorList.Items.Add(listViewItem);
ah here is how to create a listview and add items to it in wpf
check this question Add Items to Columns in a WPF ListView
In short
list view takes an object so you need to add items like that
lvInstructorList.Items.Add(lvInstructorList.Items.Add(new Instructor { firstName = inst.firstName, lastName = inst.lastName });
and you should bind to it in xaml
<ListView x:Name="lvInstructorList">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding firstName }"/>
</GridView>
</ListView.View>
Not sure why you want to loop again and again to the lvInstructorList. But you have to clear every time.
instList.Add(new Instructor { firstName = txtInstructorFirstName.Text, lastName = txtInstructorLastName.Text });
lvInstructorList.Clear();
foreach (var inst in instList)
{
lvInstructorList.Items.Add(inst);
}
It looks to me like you are not intending on binding the list view to an object, but rather just insert string values into the list view. If that is the case:
lvInstructorList.Items.Add(string.Format("{0} {1}", inst.firstName, inst.lastName));
I several objects of class:
class Person
{
public string Name { get; set; }
public string Sex { get; set; }
public int Age { get; set; }
public override string ToString()
{
return Name + "; " + Sex + "; " + Age;
}
}
and a class that has a property of type Person:
class Cl
{
public Person Person { get; set; }
}
And I want to bind Cl.Person to combobox. When I try to do it like this:
Cl cl = new cl();
comboBox.DataSource = new List<Person> {new Person{Name = "1"}, new Person{Name = "2"}};
comboBox.DataBindings.Add("Item", cl, "Person");
I get an ArgumentException. How should I modify my binding to get the correct program behavior?
Thanks in advance!
Bind to "SelectedItem":
var persons = new List<Person> { new Person() { Name = "John Doe"}, new Person() { Name = "Scott Tiger" }};
comboBox1.DisplayMember = "Name";
comboBox1.DataSource = persons;
comboBox1.DataBindings.Add("SelectedItem", cl, "Person");
For simple databinding, this will work
cl.Person = new Person{ Name="Harold" };
comboBox.DataBindings.Add("Text",cl.Person, "Name");
But I don't think that's what you want. I think you want to bind to a list of items, then select one. To bind to a list of items and show the Name property, try this:
comboBox.DataSource = new List<Person> {new Person{Name = "1"}, new Person{Name = "2"}};
comboBox.DisplayMember = "Name";
Provided your Person class overrides Equals() such that, say, a Person is equal to another if they have the same Name, then binding to the SelectedItem property will work like so:
Cl cl = new Cl {Person = new Person {Name="2" }};
comboBox.DataBindings.Add("SelectedItem", cl, "Person");
If you can't override Equals(), then you just have to make sure you're referencing a Person instance from the DataSource list, so the code below works for your specific code:
Cl cl = new Cl();
cl.Person = ((List<Person>)comboBox1.DataSource)[1];
comboBox.DataBindings.Add("SelectedItem", cl, "Person");
Try
comboBox.DataBindings.Add("Text", cl, "Person.Name");
instead
You need to tell the combobox which property on it you want to bind to which property on your object (it's Text property, in my example which will show the Name property of the selected person).
*EDIT:* Actually scrap that, I was getting confused. You almost had it, only combobox doesn;t have a property called item, you want SelectedItem instead, like this:
Cl cl = new cl();
comboBox.DataSource = new List<Person> {new Person{Name = "1"}, new Person{Name = "2"}};
comboBox.DataBindings.Add("SelectedItem", cl, "Person");
if you are using Enums may be u have a class of enums you can a combo box like this
Specify the combo box datasourse eg
comboBoxname.DataSource = Enum.GetValues(typeof(your enum));
Now lets bind the combox box since we have the data source
comboBoxname.DataBindings.Add("SelectedItem",
object,
"field of type enum in the object");