I have two listBoxes. The first listbox contains the list of traffic violations. When you click the add button and execute the code, the listbox2 got this item "ListBoxTest.Violation", not the item being displayed from the listBox1...
What is wrong with my code?
namespace ListBoxTest
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : Form
{
private List<Violation> violationList = new List<Violation>();
public MainForm()
{
InitializeComponent();
}
void MainFormLoad(object sender, EventArgs e)
{
LoadViolations(); // Initialize and add violations to violationList.
listBox1.DataSource = violationList; // Set the DataSource property.
listBox1.ValueMember = "Code";
listBox1.DisplayMember = "Description";
}
void LoadViolations()
{
Violation violation;
violation = new Violation("001", "Beating the red light");
violationList.Add(violation);
violation = new Violation("002", "Exceeding posted speed limit on the road");
violationList.Add(violation);
violation = new Violation("003", "Driving a vehicle without license to drive");
violationList.Add(violation);
violation = new Violation("004", "Driving a non registered vehicle");
violationList.Add(violation);
violation = new Violation("005", "Vehicle has no plate number");
violationList.Add(violation);
}
void BtnAddClick(object sender, EventArgs e)
{
listBox2.Items.Add(listBox1.SelectedItem); // Add item from listBox1 to listBox2;
}
}
/// <summary>
/// Violation Class
/// Properties: Code, Description
/// </summary>
public class Violation
{
private string _code;
private string _description;
public Violation(string code, string description)
{
_code = code;
_description = description;
}
public String Code
{
get { return _code; }
set { _code = value; }
}
public String Description
{
get { return _description; }
set { _description = value; }
}
}
}
Type cast the selected item to Violation. This should fix the problem.
Edit: I have modified the code to fix the issue.
private void AddClick(object sender, EventArgs e)
{
// Set the DataSource property.
listBox2.ValueMember = "Code";
listBox2.DisplayMember = "Description";
listBox2.Items.Add((Violation)listBox1.SelectedItem);
}
Make sure listbox2 has the same settings as listbox1, e.g. listbox2.ValueMember, listbox2.DisplayMember..
Related
In my app, I have a few of checkListBoxes and I need to save clicks on this list. That means for the next time I don't need to click on them again and again.
Code:
public Form2()
{
InitializeComponent();
InitializeSecondForm();
}
private void InitializeSecondForm()
{
this.Height = Properties.Settings.Default.SecondFormHeight;
this.Width = Properties.Settings.Default.SecondFormWidth;
this.Location = Properties.Settings.Default.SecondFormLocation;
this.FormClosing += SecondFormClosingEventHandler;
this.StartPosition = FormStartPosition.Manual;
}
private void SecondFormClosingEventHandler(object sender, FormClosingEventArgs e)
{
Properties.Settings.Default.SecondFormHeight = this.Height;
Properties.Settings.Default.SecondFormWidth = this.Width;
Properties.Settings.Default.SecondFormLocation = this.Location;
Properties.Settings.Default.Save();
}
I tried to use this question for my answer, but it's not working: Save CheckedListBox Items to Settings
With a simple checkBox it's not a problem, but here we have a list.
Any idea how to do it?
Perhaps saving identifiers of each checked item to a json file.
In the following I did on CheckedListBox, for multiple CheckedListBox controls you need to adjust the code to use one json file with a modified structure to account for multiple CheckedListBox control or one json file per CheckedListBox.
Example, load items into the following class
public class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public override string ToString()
{
return ProductName;
}
}
Use the following class for read/write to a json file, in this case using json.net but will work also with system.text.json.
public class JsonOperations
{
/// <summary>
/// In your app you need to setup a different file name for each CheckedListBox
/// </summary>
public static string FileName =>
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Checked.json");
/// <summary>
/// Save only checked products
/// </summary>
/// <param name="list"></param>
public static void Save(List<ProductItem> list)
{
string json = JsonConvert.SerializeObject(list, Formatting.Indented);
File.WriteAllText(FileName, json);
}
/// <summary>
/// Read back if file exists
/// </summary>
/// <returns></returns>
public static List<ProductItem> Read()
{
List<ProductItem> list = new List<ProductItem>();
if (File.Exists(FileName))
{
list = JsonConvert.DeserializeObject<List<ProductItem>>(File.ReadAllText(FileName));
}
return list;
}
}
The following classes provide methods to get checked items set checked items from json mentioned above.
public static class CheckedListBoxExtensions
{
public static List<ProductItem> IndexList(this CheckedListBox sender)
{
return
(
from item in sender.Items.Cast<Product>()
.Select(
(data, index) =>
new ProductItem()
{
ProductID = data.ProductID,
Index = index
}
)
.Where((x) => sender.GetItemChecked(x.Index))
select item
).ToList();
}
public static void SetChecked(this CheckedListBox sender, int identifier, bool checkedState = true)
{
var result = sender.Items.Cast<Product>()
.Select((item, index) => new CheckItem
{
Product = item,
Index = index
})
.FirstOrDefault(#this => #this.Product.ProductID == identifier);
if (result != null)
{
sender.SetItemChecked(result.Index, checkedState);
}
}
}
public class CheckItem
{
public Product Product { get; set; }
public int Index { get; set; }
}
Form code would resemble the following to read checked items on form shown event and save checked item on form closing event.
public partial class SaveItemsForm : Form
{
private List<Product> _products = new List<Product>();
public SaveItemsForm()
{
InitializeComponent();
Shown += OnShown;
Closing += OnClosing;
}
private void OnClosing(object sender, CancelEventArgs e)
{
List<ProductItem> checkedItems = ProductCheckedListBox.IndexList();
if (checkedItems.Count > 0)
{
JsonOperations.Save(checkedItems);
}
else
{
JsonOperations.Save(new List<ProductItem>());
}
}
private void OnShown(object sender, EventArgs e)
{
_products = SqlServerOperations.ProductsByCategoryIdentifier(1);
ProductCheckedListBox.DataSource = _products;
/*
* Search for each product by id, if in the CheckedListBox check it
*/
var items = JsonOperations.Read();
if (items.Count >0 )
{
items.ForEach( x => ProductCheckedListBox.SetChecked(x.ProductID));
}
}
}
In such conditions, I prefer to have a simple database like SQLite.
Use this database to save the user profile. user profile data will store all such data. for example, the user and password can be saved into that to remember to the user for next time login, or all settings and configurations that user selected it during using the system.
I'm learning UWP in VS2015 Community right now and having trouble with one section in regards to a ComboBox and could really use some help.
I'm writing a Bible app and have 3 ComboBoxes for Translation, Book, and Chapter. When I change the Book dropdown it should change the Chapter to 1. At least until I make a forward and back button for chapters, just covering the basics right now. When I change the Translation let's say from NIV to KJV it should change to the currently selected Book/Chapter in that translation.
I've preloaded the texts from XML and loaded them into an object called dataLoader. I'm doing selections on it via LINQ in the code below.
So right now I say something like:
private void DataLoader_Completed(object sender, EventArgs e)
{
dataLoaded = true;
cmb_Translation.ItemsSource = from t in dataLoader.Translations select new { t.TranslationShortName };
cmb_Book.ItemsSource = from b in dataLoader.Translations[0].Books select new { b.BookName };
cmb_Chapter.ItemsSource = from c in dataLoader.Translations[0].Books[0].Chapters select new { c.Index };
cmb_Book.SelectedIndex = 0;
cmb_Translation.SelectedIndex = 0;
cmb_Chapter.SelectedIndex = 0;
}
private void translationChanged()
{
chapterChanged();
}
private void bookChanged()
{
cmb_Chapter.ItemsSource = from c in dataLoader.Translations[cmb_Translation.SelectedIndex].Books[cmb_Book.SelectedIndex].Chapters select new { c.Index };
cmb_Chapter.SelectedIndex = 0;
}
private void chapterChanged()
{
textBlock_Verses.Text = dataLoader.Translations[cmb_Translation.SelectedIndex].Books[cmb_Book.SelectedIndex].Chapters[cmb_Chapter.SelectedIndex].TextLineSeparated;
}
private void cmb_Translation_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
translationChanged();
}
private void cmb_Book_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
bookChanged();
}
private void cmb_Chapter_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
chapterChanged();
}
I'm getting errors back though on the first run that the index is out of range because at first the SelectedIndex of the translation is -1, if I run translation first it will give me an out of range on the book for SelectedIndex being -1.
I want the selected index changing to trigger the proper events but as you can see that's not going to work how it is now. Also the code is pretty messy, I've started looking a bit into Binding but there are a lot of hurdles like figuring out how to bind to a property that returns a LINQ result. I'm not sure how to move forward on this and definitely appreciate any help I can get.
Combobox can have no selection - selected item is null and this is how it's initialized, so before you set SelectedInexes all are null (this means that SelectedIndex == -1):
private void DataLoader_Completed(object sender, EventArgs e)
{
dataLoaded = true;
cmb_Translation.ItemsSource = from t in dataLoader.Translations select new { t.TranslationShortName };
cmb_Book.ItemsSource = from b in dataLoader.Translations[0].Books select new { b.BookName };
cmb_Chapter.ItemsSource = from c in dataLoader.Translations[0].Books[0].Chapters select new { c.Index };
cmb_Book.SelectedIndex = 0; // <- you set here selected index for book
// which fires bookchanged even right away
// In that event cmb_Translation.SelectedIndex
// is still -1 which will surely throw exception
cmb_Translation.SelectedIndex = 0;
cmb_Chapter.SelectedIndex = 0;
}
You probably should put some check-ups if values are properly set before using them. Also think if there is a chance when there is no selection state.
private void bookChanged()
{
if (cmb_Translation.SelectedIndex >= 0)
{
cmb_Chapter.ItemsSource = from c in dataLoader.Translations[cmb_Translation.SelectedIndex].Books[cmb_Book.SelectedIndex].Chapters select new { c.Index };
cmb_Chapter.SelectedIndex = 0;
}
}
There is one hiccup with this - you will have to launch bookchanged() at the endo of DataLoader_Completed manually, as it won't process before, due to -1.
Here's the solution I came to that works, although I think maybe a better solution could have been achieved using Binding to properties I've created, some feedback on improvements could always be helpful from a design perspective. What I did essentially was create an UpdateChapterText Boolean property that when set to false won't process my SelectedIndex change events, but will still allow me to update underlying data sources and change the SelectedIndex on the fly, that way I can process events in one go, otherwise it might be fire multiple events to update the underlying data sources. I needed to be able to do this because for the chapter text view it relies on both the translation and book selected indexes to be set, but the default behavior only allows one or the other to be set before events process, which becomes unsolvable at least I think for now unless you turn off events processing I found.
/// <summary>
/// This is a helper property for setting the Translation SelectedIndex
/// </summary>
private int TranslationIndex
{
get
{
return cmb_Translation.SelectedIndex;
}
set
{
cmb_Translation.SelectedIndex = value;
}
}
/// <summary>
/// This is a helper property for setting the Book SelectedIndex
/// </summary>
private int BookIndex
{
get
{
return cmb_Book.SelectedIndex;
}
set
{
cmb_Book.SelectedIndex = value;
}
}
/// <summary>
/// This is a helper property for setting the Chapter SelectedIndex
/// </summary>
private int ChapterIndex
{
get
{
return cmb_Chapter.SelectedIndex;
}
set
{
cmb_Chapter.SelectedIndex = value;
}
}
/// <summary>
/// Retrieves the currently selected Chapter listing
/// </summary>
public IEnumerable<ChapterIndex> CurrentChapters
{
get
{
return from c in dataLoader.Translations[TranslationIndex].Books[BookIndex].Chapters select new ChapterIndex { Index = c.Index };
}
}
/// <summary>
/// Retrieves Genesis in the first loaded translation
/// </summary>
public IEnumerable<ChapterIndex> Genesis
{
get
{
return from c in dataLoader.Translations[0].Books[0].Chapters select new ChapterIndex { Index = c.Index };
}
}
public IEnumerable<BookNames> CurrentBooks
{
get
{
return from b in dataLoader.Translations[TranslationIndex].Books select new BookNames { BookName = b.BookName };
}
}
/// <summary>
/// Allows events to process on ComboBoxes and Back/Forward Buttons
/// to change Chapters, you usually don't want to do this lots of
/// times in one second if changing the Translation/Book/Chapter
/// all at one time so you may set it to false first, update your
/// variables, and then set it back to true so updating events will
/// process correctly.
/// </summary>
public bool UpdateChapterText { get; set; }
/// <summary>
/// The DataLoader object loads up the various Bible translation texts
/// </summary>
TheBible.Model.DataLoader.DataLoader dataLoader;
public MainPage()
{
this.InitializeComponent();
dataLoader = new Model.DataLoader.DataLoader();
dataLoader.Completed += DataLoader_Completed;
ApplicationView.GetForCurrentView().TryEnterFullScreenMode();
}
private void DataLoader_Completed(object sender, EventArgs e)
{
UpdateChapterText = false;
cmb_Translation.ItemsSource = from t in dataLoader.Translations select new { t.TranslationShortName };
cmb_Book.ItemsSource = from b in dataLoader.Translations[0].Books select new { b.BookName };
cmb_Chapter.ItemsSource = Genesis;
cmb_Translation.SelectedIndex = 0;
cmb_Book.SelectedIndex = 0;
UpdateChapterText = true;
cmb_Chapter.SelectedIndex = 0;
}
private void translationChanged()
{
chapterChanged();
}
private void bookChanged()
{
UpdateChapterText = false;
cmb_Chapter.ItemsSource = CurrentChapters;
UpdateChapterText = true;
cmb_Chapter.SelectedIndex = 0;
}
private void chapterChanged()
{
textBlock_Verses.Text = dataLoader.Translations[TranslationIndex].Books[BookIndex].Chapters[ChapterIndex].TextLineSeparated;
}
private void decrementChapter()
{
UpdateChapterText = false;
if (this.cmb_Chapter.SelectedIndex == 0)
{
if (this.cmb_Book.SelectedIndex > 0)
{
this.cmb_Book.SelectedIndex--;
UpdateChapterText = true;
this.cmb_Chapter.SelectedIndex = CurrentChapters.Count() - 1;
}
}
else
{
UpdateChapterText = true;
this.cmb_Chapter.SelectedIndex--;
}
UpdateChapterText = true;
}
private void incrementChapter()
{
UpdateChapterText = false;
if (this.cmb_Chapter.SelectedIndex == this.cmb_Chapter.Items.Count - 1)
{
if (this.cmb_Book.SelectedIndex < this.cmb_Book.Items.Count - 1)
{
this.cmb_Book.SelectedIndex++;
UpdateChapterText = true;
this.cmb_Chapter.SelectedIndex = 0;
}
}
else
{
UpdateChapterText = true;
this.cmb_Chapter.SelectedIndex++;
}
UpdateChapterText = true;
}
private void cmb_Translation_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (UpdateChapterText)
translationChanged();
}
private void cmb_Book_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (UpdateChapterText)
bookChanged();
}
private void cmb_Chapter_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (UpdateChapterText)
chapterChanged();
}
private void btn_Forward_Click(object sender, RoutedEventArgs e)
{
incrementChapter();
}
private void btn_Back_Click(object sender, RoutedEventArgs e)
{
decrementChapter();
}
private void btn_FullScreen_Click(object sender, RoutedEventArgs e)
{
var view = ApplicationView.GetForCurrentView();
if (view.IsFullScreenMode)
{
sym_FullScreen.Symbol = Symbol.FullScreen;
view.ExitFullScreenMode();
}
else
{
sym_FullScreen.Symbol = Symbol.BackToWindow;
view.TryEnterFullScreenMode();
}
}
I'm trying a code which changes the TextBox values when variable mapped with it changes accordingly without using TextBox changed event. I am not finding any clue to where to start please help me.
Here is the code:
public void varChange(TextBox text)
{
String name;
name="sachin";
text.Text = name;
MessageBox.Show("" + text.Text);
}
You can "extend" TextBox :
public class MeTextBox : TextBox
{
public override string Text
{
get
{
return base.Text;
}
set
{
//base.Text = value; // use it or not .. whatever
MyTextWasChanged();
}
}
void MyTextWasChanged()
{
String name;
name="sachin";
//text.Text = name;
base.Text = name;
MessageBox.Show("" + text.Text);
}
}
If that's not what you're looking for then give some more details and I'll update this answer.
You can use a BindingSource
public partial class Form1 : Form
{
private System.Windows.Forms.BindingSource form1BindingSource;
public string BindedProp { get; set; } //Variable or property binded with TextBox
public Form1()
{
InitializeComponent();
this.form1BindingSource = new System.Windows.Forms.BindingSource(new System.ComponentModel.Container());
this.form1BindingSource.DataSource = typeof(binding.Form1);
this.textBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.form1BindingSource, "BindedProp", true));
this.form1BindingSource.DataSource = this;
}
//add a button control to assing value code event click
private void btAssingValueProperty_Click(object sender, EventArgs e)
{
BindedProp = "Value assigned";
form1BindingSource.ResetBindings(false);
}
//add a other button control to show value code event click
private void btShowValueProperty_Click(object sender, EventArgs e)
{
MessageBox.Show(BindedProp);
}
}
I am trying to store multiple values from numerous buttons so I can return values of two or more things e.g. if chocolate and vanilla clicked both prices and names can be returned. I will also need to make calculations on the data set later. Whenever I return the data only the most recent values return rather than all of those I have selected.
private void VanillaBtn_Click(object sender, RoutedEventArgs e)
{
items.Price = 450;
items.Name = "Vanilla"
}
private void ChocolateBtn_Click(object sender, RoutedEventArgs e)
{
items.Price = 500;
items.Name = "Chocolate";
}
This is my class, any help or tips would be appreciated.
class Items
{
private int thePrice;
private string theName;
public int Price
{
get
{
return thePrice;
}
set
{
thePrice = value ;
}
}
public string Name
{
get
{
return theName;
}
set
{
theName = value;
}
}
Keep a list of whatever was clicked.
private List<Items> selectedItems = new List<Items>();
So, every time something is clicked, you store the object in the list defined above.
private void VanillaBtn_Click(object sender, RoutedEventArgs e)
{
var newItem = new Items();
newItem.Price = 450;
newItem.Name = "Vanilla";
selectedItems.Add(newItem);
}
I am having this very strange problem where i am creating a list of some objects in one class then trying to access it in another class but it's coming empty in other class:
My first class where i am populating the list:
namespace dragdrop
{
struct BR
{
private string var;
public string Var
{
get { return var; }
set { var = value; }
}
private string equalsTo;
public string EqualsTo
{
get { return equalsTo; }
set { equalsTo = value; }
}
private string output;
public string Output
{
get { return output; }
set { output = value; }
}
private string els;
public string Els
{
get { return els; }
set { els = value; }
}
private string elsOutput;
public string ElsOutput
{
get { return elsOutput; }
set { elsOutput = value; }
}
}
public partial class Form1 : Form
{
//******************
private List<BR> list = new List<BR>(); //This is the list!
//******************
internal List<BR> List
{
get { return list; }
set { list = value; }
}
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string[] vars = new string[] { "Name", "Gender", "Age", "Address", "email" };
comboBox1.DataSource = vars;
}
private void button1_Click(object sender, EventArgs e)
{
BR b = new BR();
b.Var = comboBox1.SelectedItem.ToString();
b.EqualsTo = textBox1.Text;
b.Output = textBox2.Text;
list.Add(b);
//*****************
textBox1.Text = List.Count.ToString(); //This gives the correct count value!
//*****************
//this.Close();
}
}
}
I am accessing it in second class like:
namespace dragdrop
{
public partial class Ribbon1
{
private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
{
}
private void button1_Click(object sender, RibbonControlEventArgs e)
{
Form1 form = new Form1();
List<BR> l = form.List; ;
//*******************
MessageBox.Show(form.List.Count.ToString()); //This strangely gives count 0!
//*******************
}
}
}
I have even tried making everything public in first class but no matter what i do, im always getting empty list in second class.
The is no relation what-so-ever between Form1 and Ribbon1, how can one then access an instance of the other?
With this:
Form1 form = new Form1(); // new instance of Form1
List<BR> l = form.List; ; // of course the list is empty in a new instance!
you can never access values from another instance of Form1.
Since I have no idea how your classes are connected I cannot give you more advice than have a look at this good overview of OO-relationships. You have to connect them somehow for it to work, I would very much recommend composition // aggregation (same thing, different schools).
All i needed to do was make the list a static member in class one, that solved the issue of having different value when i tried to create a new instance of Form1 in Ribbon1 class.
private static List<BR> list = new List<BR>();