C# databinding on combobox - c#

I can't understand the following 2 issues given this code. I mapped a combobox to a custom object and I want each time that the selected value change on the combobox, the custom object changes too.
public partial class MainForm : Form
{
private Person _person;
public MainForm()
{
InitializeComponent();
_person = new Person();
//Populating the combox, we have this.comboBoxCities.DataSource = this.cityBindingSource;
cityBindingSource.Add(new City("London"));
cityBindingSource.Add(new City("Paris"));
_person.BirthCity = new City("Roma");
cityBindingSource.Add(_person.BirthCity);
cityBindingSource.Add(new City("Madrid"));
//Doing the binding
comboBoxCities.DataBindings.Add("SelectedItem", _person, "BirthCity");
}
private void buttonDisplay_Click(object sender, EventArgs e)
{
MessageBox.Show("BirthCity=" + _person.BirthCity.Name);
}
private int i = 0;
private void buttonAddCity_Click(object sender, EventArgs e)
{
City city = new City("City n°" + i++);
cityBindingSource.Add(city);
comboBoxCities.SelectedItem = city;
}
}
public class Person
{
private City _birthCity;
public City BirthCity
{
get { return _birthCity; }
set
{
Console.WriteLine("Setting birthcity : " + value.Name);
_birthCity = value;
}
}
}
public class City
{
public string Name { get; set; }
public City(string name) { Name = name; }
public override string ToString() { return Name; }
}
1 - why when I manually select twice in a row (or more) different value on the combobox, I got only one call to BirthCity.Set witht he last selected value (and the call seems firing only when the combobox lost the focus) ?
2 - why when I click buttonAddCity and then buttonDisplay, the diplayed city is not the one selected (not the one displayed in the comobox )

why when I manually select twice in a row (or more) different value on the combobox, I got only one call to BirthCity.Set witht he last selected value (and the call seems firing only when the combobox lost the focus) ?
That's how Data Binding works, data is moved from the control to the property when validation occurs, and validation occurs when the control loses focus.
why when I click buttonAddCity and then buttonDisplay, the diplayed city is not the one selected (not the one displayed in the comobox )
I don't know. I created a simple form (Visual C# Express 2008 using .Net 3.5 SP1) and pasted your code pretty much verbatim, and it works as expected: it shows the new city in the combo box.
If you add comboBoxCities.Focus (); to the end of buttonAddCity_Click (), you'll make sure the new city gets pushed into _person.BirthCity earlier rather than on ValidateChildren ().

Related

Xamarin Checkbox isn't "linking" properly to ObservableCollection in App.xaml.cs

I'm, having a Listview, with bunch of "Modules" in one ObservableCollection, which has been set as the ItemsSource. This collection has been set as:
public static ObservableCollection<Module> Modules { get; set; } in App.xaml.cs to make it global.
When I click the checkbox in the list, it will launch this function:
private void ModuleCheckbox_CheckedChanged(object sender, CheckedChangedEventArgs e)
{
var checkbox = (CheckBox)sender;
var item = (Module)checkbox.BindingContext;
item.ModuleIsChecked = checkbox.IsChecked;
foreach(Module m in App.Modules)
{
Console.WriteLine(m.Name + " Value: " + m.ModuleIsChecked);
}
}
As you can see, I'm trying to set the property: ModuleIsChecked to be the same, as the checkbox, which in this case should be true or false. Now, when I click the checkbox, and the foreach-loop goes trough, the values are correct. When I go to the new "page" by using the
Navigation.PushAsync(new NewSite()); function and run the loop again, none of the Modules have ModuleIsChecked value as set before. How is this possible?
Module has the following attributes:
public string Description { get; set; }
public bool IsVisible { get; set; }
public bool ModuleIsChecked { get; set; }
public ObservableCollection<Question> QuestionList { get; set; }
edit as requested, here's the code at the new page, where I run through the same list just to see, if my selections have been "stuck" into that ObservableCollection:
public partial class NewSite : ContentPage
{
public Questions()
{
InitializeComponent();
BindingContext = new App();
foreach(Module m in App.Modules)
{
Console.WriteLine("Module: {0} ModuleisChecked: {1}", m.Name, m.ModuleIsChecked);
}
And here, the Console shows, that all of the values are False. Any ideas?
Thank you to Jason in the comments! (I don't know how to link you here, sorry!)
The problem lies in here:
BindingContext = new App();
As Jason said, that creates new instance of the App instead of using the existing one, which I just edited. Commenting this out and I was able to get this working as intended. Thank you!
Can be marked as solved, thanks!

Populate listview multiple times using C# Class

I am trying to populate a listview each time a button is selected. At the moment I have the button populating the listview once each time. Each time a new value is entered it will overwrite the current listview.
I want to be able to add in a new item and continue till there is multiple rows.
protected void btnAddSkuBarcode_Click(object sender, EventArgs e)
{
var SKUS = new List<SkuBar>
{
new SkuBar {SkuBarcode = txtSkuBarcode.Text , Qty = txtQty.Text},
};
lvWebLabels.DataSource = SKUS;
lvWebLabels.DataBind();
}
public class SkuBar
{
public string SkuBarcode { get; set; }
public string Qty { get; set; }
}
Currently you're creating a new variable (SKUS) every time the button is clicked. When you bind to that new list, you lose anything previously bound to the control.
Since the list needs to persist in a greater scope than just the method, put it in something like class scope:
List<SkuBar> SKUS = new List<SkuBar>();
Then just add to the existing list:
protected void btnAddSkuBarcode_Click(object sender, EventArgs e)
{
SKUS.Add(new SkuBar {SkuBarcode = txtSkuBarcode.Text , Qty = txtQty.Text});
lvWebLabels.DataSource = SKUS;
lvWebLabels.DataBind();
}
Note that this will only work in a stateful system. If by chance you're using WebForms then the object itself is also dropped from scope for each request, so you'd need to persist the data somewhere else. Session state, database, etc.
You're creating a new List<T> every time the button is clicked so you lose the previous one. Define the List<T> outside of the button press so it can be re-used:
namespace YourNamespace
{
public class YourClass
{
List<SkuBar> SKUS;
public YourClass() // Or form load or whatever
{
SKUS = new List<SkuBar>();
}
protected void btnAddSkuBarcode_Click(object sender, EventArgs e)
{
SKUS.Add(new SkuBar {SkuBarcode = txtSkuBarcode.Text , Qty = txtQty.Text});
lvWebLabels.DataSource = SKUS;
lvWebLabels.DataBind();
}
}
}

DropDownList selects top value only

I have a textbox that will be filled by a button click.
When i Click the button, it will compare some values and then copy the value from a dropdownlist it to the first textbox.
But the dropdownlist only copies the first value, even if i select a second or third value, it will always copy the first.
Here is my code:
protected void BtnOrderKoppelen_Click(object sender, EventArgs e)
{
if(DDLLijnRequest.Text == "Lijn1")
{
TbProd5.Text = DDLVrijgeefOrder.Text;
}
else if (DDLLijnRequest.Text == "Lijn2")
{
TbProd6.Text = DDLVrijgeefOrder.Text;
}
else if (DDLLijnRequest.Text == "Lijn3")
{
TbProd7.Text = DDLVrijgeefOrder.Text;
}
else if (DDLLijnRequest.Text == "Lijn4")
{
TbProd8.Text = DDLVrijgeefOrder.Text;
}
}
DDLLijnRequest= a dropdownlist for my production line comparison
TbProd(5 till 8) = are textboxes where data from DDLVrijgeefOrder has to go to
DDLVrijgeefOrder = a dropdownlist where i select an order and want it to copy to the textboxes.
Is there a way that it could copy any value that i have selected in DDLVrijgeefOrder?
This is my pageload, it has no connection yet with the button click or the dropdownlist. Do i have to add something here? :
protected void Page_Load(object sender, EventArgs e)
{
if (Session["MesLogin"] == null)
{
Response.Redirect("StartPagina.aspx");
}
else
{
LblSession.Text = "Welcome" + Session["MesLogin"].ToString();
}
}
Thank you in advance!
Hope you bind the drop-down value all the time in Page_load event. Drop down data source should be binded only in very first time otherwise it will always bind to first value.
Example:
Void Page_Load()
{
if(!IsNotPostBack)
{
// bind drop down values here
}
}
If the above solution doesn't help, please post some more code like Page_Load event
Based on the context of your question you are using WinForms right?
The following link provides a good answer to your question:
How to create a drop down menu in WinForms and C#
Note that you can add any type of item to the ComboBox. If you don't
specify the DisplayMember and ValueMember properties, the ComboBox
uses the ToString method of the object in order to determine the text
displayed and you can retrieve the selected item (not selected value)
through the SelectedItem property.
class Person
{
public int PersonID { get; set }
public string FirstName { get; set; }
public string LastName { get; set; }
public override string ToString()
{
return FirstName + " " + LastName;
}
}
Eventually you can do
Person selectedPerson = (Person)myComboBox.SelectedItem;
int personID = selectedPerson.PersonID;

Read the Value of an Item in a listbox

I'm developing a small windows store application in C# where I have populated the values and content for a listbox using the following code snippet.
code 1 : adds the song title as a item to a listbox, using the Song class to create the item
private void addTitles(string title, int value)
{
Song songItem = new Song();
songItem.Text = title;
songItem.Value = value;
listbox1.Items.Add(songItem); // adds the 'songItem' as an Item to listbox
}
code 2 : Song class which is used to set values to each item ('songItem')
public class Song
{
public string Text { get; set; }
public int Value { get; set; }
public override string ToString()
{
return Text;
}
}
Population content to the listbox is functioning currently.
What I want is to get the 'Value' of each item on a Click event, on run-time.
For that purpose, how can I read(extract) the Value of the selected Item in the listbox, in C#? ( Value is the songItem.Value )
code 3 : I have tried this code, as trying to figure out a solution, but it didn't work
private void listbox1_tapped(object sender, TappedRoutedEventArgs e)
{
Int selectedItemValue = listbox1.SelectedItem.Value();
}
Therefore it would be really grateful if someone can help me, as I'm an Amateur.
not sure about the "TappedRoutedEventArgs", but I would do
private void listbox1_tapped(object sender, TappedRoutedEventArgs e)
{
var selectedSong = (Song)listbox1.SelectedItem;
if (selectedSong != null) {
var val = selectedSong.Value;
}
}
because SelectedItem is an Object (which doesn't know about the Value property), so you have to cast it to a Song first.
By the way, Value is a property, not a method, so you don't need the parenthesis.
Try like this:
Song song=listbox1.SelectedItem as Song;
or this:
var selected = listbox1.SelectedValue as Song;
Try something like this :
if (listbox1.SelectedRows.Count>0){
Song song=(Song)listbox1.SelectedItem;
int value=song.Value;
}

Change bound Property when programmatically changing SelectedIndex

I've set up a simple form. A ListBox takes values from a list in the 'business object' displaying the Name property and providing the Value property.
In additon the ListBox's SelectedItem property is bound to a property in the same business object.
Using the UI to select a value from the list correctly changes the objects property (checked when the button is clicked) and the correct value is available. So far so good.
However, if the ListBox's SelectedIndex property is changed in the code, then the UI correctly changes as expected but the business property does not change - it would appear to have missed the change event. This is true for both setting in the constructor and in the button event handler (see the code).
What have I missed or what am I doing incorrectly.
(I've only included the code I've written - not VS wizard generated stuff)
class Frequency
{
public String Name { get; set; }
public Int16 Value { get; set; }
public Frequency(String name, Int16 value)
{
Name = name;
Value = value;
}
}
class FrequencyList : System.ComponentModel.BindingList<Frequency>
{
}
class Model
{
public static FrequencyList FrequencyValues = new FrequencyList()
{
new Frequency("Slowest", 100),
new Frequency("Slow", 150),
new Frequency("Medium", 1000),
new Frequency("Fast", 5500),
new Frequency("Fastest", 10000)
};
public Frequency StartFrequency { get; set; }
public void DoStuff()
{
if (StartFrequency == null)
return;
Int16 freq = StartFrequency.Value;
}
}
public partial class Form1 : Form
{
private Model myModel = new Model();
public Form1()
{
InitializeComponent();
// Bind the list to a copy of the static model data
this.listBox1.DataSource = Model.FrequencyValues;
// Bind the control to the model value
this.listBox1.DataBindings.Add("SelectedItem", myModel, "StartFrequency");
// Select the start value
this.listBox1.SelectedIndex = 3;
}
private void button1_Click(object sender, EventArgs e)
{
Int16 f = (Int16)listBox1.SelectedValue;
this.myModel.DoStuff();
int new_index = listBox1.SelectedIndex + 1;
if (new_index >= listBox1.Items.Count)
new_index = 0;
listBox1.SelectedIndex = new_index;
}
}
You don't want the Click event, you want the SelectedIndexChanged event. This will trigger regardless of whether the user or the program instigates the change.

Categories

Resources