I made an mp3 player in C#. If I select the songs at once, they automatically play one after the other, but when it comes to a song I added later, I get a "System.IndexOutOfRangeException" error. When I add music later, I want the song to play automatically one after the other, how can I do that?
string[] yol, dosya;
private void Btn_Muzik_Ekle_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Multiselect = true;
if (ofd.ShowDialog()==System.Windows.Forms.DialogResult.OK)
{
dosya = ofd.SafeFileNames;
yol = ofd.FileNames;
for (int x = 0; x < dosya.Length; x++)
{
Lb_Muzik_Listesi.Items.Add(dosya[x]);
}
}
}
private void Lb_Muzik_Listesi_SelectedIndexChanged(object sender, EventArgs e)
{
//This Is Where I Got The Error
OynatmaEkranı.URL = yol[Lb_Muzik_Listesi.SelectedIndex];
OynatmaEkranı.Ctlcontrols.play();
try
{
var file = TagLib.File.Create(yol[Lb_Muzik_Listesi.SelectedIndex]);
var bin = (byte[])(file.Tag.Pictures[0].Data.Data);
Pb_Muzik_Kapak.Image = Image.FromStream(new MemoryStream(bin));
}
catch
{
}
}
private void Zamanlayıcı_Tick(object sender, EventArgs e) //Timer
{
if (OynatmaEkranı.playState==WMPLib.WMPPlayState.wmppsPlaying)
{
Pb_Muzik.Maximum=(int)OynatmaEkranı.Ctlcontrols.currentItem.duration;
Pb_Muzik.Value = (int)OynatmaEkranı.Ctlcontrols.currentPosition;
try
{
Lbl_Muzik_Sure.Text = OynatmaEkranı.Ctlcontrols.currentPositionString;
Lbl_Muzik_Bitis.Text = OynatmaEkranı.Ctlcontrols.currentItem
.durationString.ToString();
}
catch
{
}
}
if (Pb_Muzik.Value==Pb_Muzik.Maximum)
{
if (Lb_Muzik_Listesi.SelectedIndex<Lb_Muzik_Listesi.Items.Count-1)
{
Lb_Muzik_Listesi.SelectedIndex = Lb_Muzik_Listesi.SelectedIndex + 1;
}
}
}
You can avoid this problem managing your data in the ListBox. Create a class with your required info (the file and the name):
public class MuzikItem
{
public MuzikItem(string file)
{
this.Text = System.IO.Path.GetFileNameWithoutExtension(file);
this.Url = file;
}
public string Text { get; set; }
public string Url { get; set; }
public override string ToString()
{
// This is the text to show in ListBox
return this.Text;
}
}
Add items to the ListBox using this class:
foreach (var file in ofd.FileNames)
{
var item = new MuzikItem(file);
Lb_Muzik_Listesi.Items.Add(item);
}
And use it:
var item = Lb_Muzik_Listesi.SelectedItem as MuzikItem;
if (item != null)
{
OynatmaEkranı.URL = item.Url;
OynatmaEkranı.Ctlcontrols.play();
try
{
var file = TagLib.File.Create(item.Url);
var bin = (byte[])file.Tag.Pictures[0].Data.Data;
Pb_Muzik_Kapak.Image = Image.FromStream(new MemoryStream(bin));
}
catch
{
}
}
You try to get the selected item as a MuzikItem (all your items are of this class so this return null only when no item is selected) and with this, you have the Url.
UPDATE
I like manage this things with events. In your Ticks methods:
if (Pb_Muzik.Value == Pb_Muzik.Maximum)
{
OnSongFinished();
}
And create a method to manage this event:
private void OnSongFinished()
{
if (Lb_Muzik_Listesi.SelectedIndex < Lb_Muzik_Listesi.Items.Count - 1)
{
Lb_Muzik_Listesi.SelectedIndex = Lb_Muzik_Listesi.SelectedIndex + 1;
}
else
{
// Stop the player
OynatmaEkrani.Ctlcontrols.stop();
}
}
Related
so what i would like to is setting back some attributes after an Custom Event is finished.
Scenario i have a save BackupDrives Class that does collection of data and then offers a Event to be called after its done.
Changing object properties can be done by button click, what i would like is to set them back to the same value after the event is finished.
Button click does the thing :
private void bbdrives_Click(object sender, RoutedEventArgs e)
{
backup.SaveDrives += OnSavingDrives;
backup.DrivesSave();
Drive_text.Visibility = Visibility.Visible;
drives_progres.Visibility = Visibility.Visible;
drives_progres.IsIndeterminate = true;
}
Now the triggered event method is not able to change the properties back.
private void OnSavingDrives(object sender, DrivesEventArgs e)
{
Directory.CreateDirectory(....);
File.WriteAllLines(e.Something, e.List2ToSave);
File.WriteAllLines(e.Something_lse, e.List1ToSave);
Drive_text.Visibility = Visibility.Collapsed;
drives_progres.Visibility = Visibility.Collapsed;
drives_progres.IsIndeterminate = false;
}
How do i do this. Since this does not work.
And on other thig here to - when i run the GUI i need to click 2 times one the same button to start it all. Done Code Clean + Rebuild. Still the same.
---EDIT---
As for code here you go.
This is a Class for collecting method and event.
public class DrivesEventArgs : EventArgs
{
string MYDOC = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
const string backup_Drives = "....";
const string backup_Letters = "...";
public List<string> List1ToSave = new List<string>();
public List<string> List2ToSave = new List<string>();
public string SAVE_DRIVE_Letter
{
get
{
string name = Path.Combine(MYDOC, backup_Letters);
return name;
}
}
public string SAVE_DRIVE_Path
{
get
{
string name = Path.Combine(MYDOC, backup_Drives);
return name;
}
}
}
public class DrivesBackup
{
private const string path = "Network";
private List<string> drives_to_save = new List<string>();
private List<string> letters_for_drives = new List<string>();
private RegistryKey reg1, reg2;
public event EventHandler<DrivesEventArgs> SaveDrives;
public void DrivesSave()
{
var data = new DrivesEventArgs();
try
{
if (drives_to_save.Count == 0)
{
reg1 = Registry.CurrentUser.OpenSubKey(path);
string[] mounted_drives = reg1.GetSubKeyNames();
foreach (var drive in mounted_drives)
{ //get all UNC Paths from mounted_drives
string[] getUNC = { path, drive };
string fullUNC = Path.Combine(getUNC);
reg2 = Registry.CurrentUser.OpenSubKey(fullUNC);
string UNCPath = reg2.GetValue("RemotePath").ToString(); //getting UNC PATH
Console.WriteLine(UNCPath);
data.List1ToSave.Add(drive.ToString());
data.List2ToSave.Add(UNCPath);
OnSaveDrives(data);
}
}
}
catch (Exception er)
{
throw er;
}
}
protected virtual void OnSaveDrives(DrivesEventArgs eD)
{
SaveDrives?.Invoke(this, eD);
}
Now here is the MAINWINDOW WPF
public partial class MainWindow : Window
{
DrivesBackup backup = new DrivesBackup();
public MainWindow()
{
InitializeComponent();
}
private void bbdrives_Click(object sender, RoutedEventArgs e)
{
backup.DrivesSave();
backup.SaveDrives += OnSavingDrives;
Drive_text.Visibility = Visibility.Visible;
drives_progres.Visibility = Visibility.Visible;
drives_progres.IsIndeterminate = true;
}
private void OnSavingDrives(object sender, DrivesEventArgs e)
{
Directory.CreateDirectory(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), #"SEG-Backup"));
File.WriteAllLines(e.SAVE_DRIVE_Path, e.List2ToSave);
File.WriteAllLines(e.SAVE_DRIVE_Letter, e.List1ToSave);
Drive_text.Visibility = Visibility.Collapsed;
drives_progres.Visibility = Visibility.Collapsed;
drives_progres.IsIndeterminate = false;
}
}
Now i do hope this would make some things more clear.
I create a class that I define some variables with their properties.
also I have two class "Form1" and "Form2".
I assign values to this variables in "Form1" but when I want to use the values in "Form2" after I assigned them and show them through MessageBox.Show(), I find out the variables are empty.
class Property
{
private string a_username;
private string a_email;
public string username
{
get { return a_username; }
set { a_username = value; }
}
public string email
{
get { return a_email; }
set { a_email = value; }
}
public string password { get; set; } = "88306540";
}
the assignment: (this function is in "Form1")
Property pro = new Property();
private void CreateUserInform()
{
userid = File.ReadLines(filePath).Skip(idx).Take(1).First();
// MessageBox.Show(userid);
HtmlElementCollection elemcol = webBrowser2.Document.GetElementsByTagName("option");
int i = 0;
string[] mailservices = new string[elemcol.Count];
foreach (HtmlElement elem in elemcol)
{
mailservices[i] = elem.InnerText;
i += 1;
}
pro.username = userid;
Random rand = new Random();
mailservice = mailservices[rand.Next(10)];
pro.email = pro.username + mailservice;
wb2func_create_mail();
}
call function: (this function is in "Form2" and it called after previous function.)
Property pro = new Property();
public void signup_fill()
{
HtmlElementCollection elemcol = site.Document.GetElementsByTagName("input");
foreach (HtmlElement elem in elemcol)
{
if (elem.Name == "login")
elem.SetAttribute("value", pro.username);
if (elem.Name == "remail")
elem.SetAttribute("value", pro.email);
if (elem.Name == "password")
elem.SetAttribute("value", pro.password);
if (elem.Name == "password2")
elem.SetAttribute("value", pro.password);
}
MessageBox.Show(pro.username);
}
I should mention that the "password" variable was shown pretty good but the others were shown empty.
also when I call them in "Form1" that I used to define them, it works just fine and shows the correct assignment.
the completely Form2 codes:
namespace Bypassing
{
public partial class Form2 : Form
{
string referal_link;
Property pro = new Property();
public Form2(Property form1Property)
{
InitializeComponent();
pro = form1Property;
}
public void signup_fill()
{
HtmlElementCollection elemcol = site.Document.GetElementsByTagName("input");
foreach (HtmlElement elem in elemcol)
{
if (elem.Name == "login")
elem.SetAttribute("value", pro.username);
if (elem.Name == "remail")
elem.SetAttribute("value", pro.email);
if (elem.Name == "password")
elem.SetAttribute("value", pro.password);
if (elem.Name == "password2")
elem.SetAttribute("value", pro.password);
}
MessageBox.Show(pro.username);
}
private void btn_fill_Click(object sender, EventArgs e)
{
signup_fill();
}
private void btn_logout_Click(object sender, EventArgs e)
{
HtmlElementCollection elemcol = site.Document.GetElementsByTagName("a");
foreach (HtmlElement elem in elemcol)
{
if (elem.InnerText == " Log out ")
elem.InvokeMember("click");
}
}
private void btn_next_link_Click(object sender, EventArgs e)
{
}
public bool btn_fill_enabled
{
get { return btn_fill.Enabled; }
set { btn_fill.Enabled = value; }
}
public bool btn_logout_enabled
{
get { return btn_logout.Enabled; }
set { btn_logout.Enabled = value; }
}
public bool btn_next_link_enabled
{
get { return btn_next_link.Enabled; }
set { btn_next_link.Enabled = value; }
}
private void avelon_site_Completed(object sender, WebBrowserNavigatedEventArgs e)
{
Form1 main_win = new Form1();
main_win.text_edit();
}
}
}
Form1 codes:
namespace BitcoinCloudMiningBypassApp
{
public partial class Form1 : Form
{
private string mailservice;
private string userid;
int idx = 29;
bool wb1flag = true;
bool wb2flag = true;
bool wb1ready = false;
bool wb2ready = false;
bool workflag = false;
bool start = false;
string filePath;
//StreamWriter file2 = new StreamWriter("avelon_users_email.txt", true);
//StreamWriter file = new StreamWriter("avelon_referal_links.txt", true);
Property pro = new Property();
private void OpenFileDialogForImportingUserId()
{
//var fileContent = string.Empty;
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.InitialDirectory = "C:\\";
openFileDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog.FilterIndex = 1;
openFileDialog.RestoreDirectory = true;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
//Get the path of specified file
filePath = openFileDialog.FileName;
btn_start.Enabled = true;
////Read the contents of the file into a stream
//var fileStream = openFileDialog.OpenFile();
//using (StreamReader reader = new StreamReader(fileStream))
//{
// fileContent = reader.ReadToEnd();
//}
}
}
}
private void CreateUserInform()
{
userid = File.ReadLines(filePath).Skip(idx).Take(1).First();
// MessageBox.Show(userid);
HtmlElementCollection elemcol = webBrowser2.Document.GetElementsByTagName("option");
int i = 0;
string[] mailservices = new string[elemcol.Count];
foreach (HtmlElement elem in elemcol)
{
mailservices[i] = elem.InnerText;
i += 1;
}
pro.username = userid;
Random rand = new Random();
mailservice = mailservices[rand.Next(10)];
pro.email = pro.username + mailservice;
//MessageBox.Show(avelon_email);
wb2func_create_mail();
}
public Form1()
{
InitializeComponent();
webBrowser2.Navigate("https://temp-mail.org/en/option/change/");
}
private void btn_start_Click(object sender, EventArgs e)
{
Form2 avelon = new Form2(pro);
avelon.Show();
//VPN vpn = new VPN();
// MessageBox.Show(vpn.ConnectVPN(vpn.SetServer(0)).ToString());
CreateAvelonUserInform();
start = true;
btn_load.Enabled = false;
btn_start.Enabled = false;
avelon.btn_logout_enabled = true;
btn_refresh.Enabled = false;
}
private void Form1_Load(object sender, EventArgs e)
{
btn_load.Enabled = false;
btn_start.Enabled = false;
btn_next.Enabled = false;
//Process.Start("cmd.exe", "taskkill / F / im notepad.exe");
}
private void webBrowser2_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (wb2flag)
{
wb2flag = false;
wb2ready = true;
if (!start)
btn_load.Enabled = wb2ready;
}
else
{
text_edit();
}
}
private void wb2func_create_mail()
{
HtmlElementCollection elemcol = webBrowser2.Document.GetElementsByTagName("option");
foreach (HtmlElement elem in elemcol)
{
if (elem.InnerText == mailservice)
elem.SetAttribute("selected", "selected");
}
HtmlElementCollection elemcol2 = webBrowser2.Document.GetElementsByTagName("input");
foreach (HtmlElement elem in elemcol2)
if (elem.GetAttribute("name") == "mail")
elem.SetAttribute("value", pro.username);
//wb2flag = true;
//workflag = true;
webBrowser2.Document.GetElementById("postbut").InvokeMember("click");
}
private void btn_load_Click(object sender, EventArgs e)
{
//OpenFileDialogForImportingUserId();
VPN vpn = new VPN();
MessageBox.Show(vpn.ConnectVPN(vpn.SetServer(0)).ToString());
//Process.Start("C:\\Users\\Hossein\\Desktop\\output.bat");
//MessageBox.Show(Environment.GetEnvironmentVariable("a", EnvironmentVariableTarget.Process));
//MessageBox.Show(Environment.GetEnvironmentVariable("a", EnvironmentVariableTarget.User));
//MessageBox.Show(Environment.GetEnvironmentVariable("a", EnvironmentVariableTarget.Machine));
}
public void text_edit()
{
txt_username.TextChanged += new EventHandler(text_change);
txt_username.Text = pro.username;
txt_email.Text = pro.email;
}
private void btn_next_Click(object sender, EventArgs e)
{
}
private void btn_refresh_Click(object sender, EventArgs e)
{
webBrowser2.Navigate("https://temp-mail.org/en/option/change/");
}
private void text_change(object s , EventArgs e)
{
Form2 avelon = new Form2(pro);
avelon.btn_fill_enabled = true;
}
}
}
Seems that password is showing fine as it's defined at the Property class itself so, each time you create a new object of that class, it will be setted by default untill you change it.
The reason you don't see the data from Form 1 at Form 2 seems to be that you aren't passing the Property object from Form 1 to Form 2, so you have a Property object filled with data at Form 1 but at Form 2 you remain with a newly created Property object. Just modify the Form 2 constructor so it accepts a Property parameter and pass it from Form 1.
Example (this goes on your Form2's code):
public Form2 (Property form1Property){
InitializeComponent();
pro = form1Property;
}
That creates a code that executes each time you create a new Form2 and requires you to pass a Property object to create it (new Form2(pro); in Form1) so it assigns Form2's Property object to the one you passed when creating it's object on Form1.
Also make your Property class public, so you can use it as a parameter at Form2's constructor.
More info about constructors here
Hope this helps you!
P.S: Looking at your code I see that you're creating a global Form2 object. You should create it at btn_start_Click before you are showing it, so data is filled up correctly (when you show it your Form1's Property object is filled, now when you create it it's not filled)
I am currently writing an application in WPF C# that is some kind of helper for other processes which are written in Java. Those other processes require a configuration.csv in which different "names" are listed with a column that says "SKIP". If the column is X at Skip, my java program will skip those names and therefore their dependent processes.
If I open the CSV with Excel and edit the rows, everything works perfectly fine. That's not the problem. What I want to achieve is to list the rows into a DataGrid in a WPF App (except the first and last row), where the user can tick a checkbox to decide if he wants to skip that specific name or not. By pressing Save, the .CSV gets updated.
I already wrote some code with a friend who's more familiar with this topic. It worked fine in WinForms but doesn't work on WPF. We are not able to get the values of the checkboxes and not able to save them into the CSV.
CODE:
private void OBJ_SaveButton_Click(object sender, RoutedEventArgs e)
{
if (OBJ_DataGrid.Items.Count == 0)
{
MessageBox.Show("Kein Datensatz in der View.");
return;
}
/*if (Directory.Exists(path))
{
if (File.Exists(filepath))
{
string tmp = null;
try
{
FileStream fileStr = new FileStream(filepath, FileMode.Create);
StreamWriter strWriter = new StreamWriter(fileStr);
strWriter.WriteLine("SFObject;Skip");
for(int i=0;i< itmGrd.Count;i++)
{
switch (itmGrd[i].ItemValue)
{
case true:
tmp = itmGrd[i].ItemName + ";X";
break;
case false:
tmp = itmGrd[i].ItemName + ";";
break;
}
strWriter.WriteLine(tmp);
}
strWriter.WriteLine("SuccessMSG;");
strWriter.Close();
fileStr.Close();
LoadConf();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
else
MessageBox.Show("ERR_F0: Pfad nicht gefunden.");
}
else
MessageBox.Show("ERR_D0: Pfad nicht gefunden.");*/
}
private void OBJ_ReloadButton_Click(object sender, RoutedEventArgs e)
{
}
private void OBJ_DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
private void OBJ_DataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
MessageBox.Show(e.Row.ToString());
}
void OnChecked(object sender, RoutedEventArgs e)
{
MessageBox.Show(e.Source.ToString());
}
}
public class ItemGrid
{
public ItemGrid(string name, bool rval)
{
ItemName = name;
ItemValue = rval;
}
public string ItemName { set; get; }
public bool ItemValue { set; get; }
}
public class ItemsGrid : List<ItemGrid>
{
public string path = null;
public string filepath = null;
public ItemsGrid()
{
path = String.Format(#"{0}\build\", Environment.CurrentDirectory);
filepath = Path.Combine(path + "configuration.csv");
if (Directory.Exists(path))
{
if (File.Exists(filepath))
{
string line = null;
StreamReader file = new StreamReader(filepath);
while ((line = file.ReadLine()) != null)
{
if (!line.Equals("SFObject;Skip") && !line.Equals("SuccessMSG;"))
{
string input = (line.IndexOf(";X") != -1 ? (line.Replace(";X", "")) : (line.Replace(";", "")));
Add(new ItemGrid(input, (line.IndexOf(";X") != -1 ? (true) : (false))));
}
}
file.Close();
}
else
MessageBox.Show("ERR_F0: Pfad nicht gefunden.");
}
else
MessageBox.Show("ERR_D0: Pfad nicht gefunden.");
//Add(new ItemGrid("Tom", false));
// Add(new ItemGrid("Jen", false));
}
}
This is how it looks (and should look like).
CSV:
I hope that you guys can help me out, I really don't understand why it's not working. I also have to admit that I am not any near of being proficient in C#.
I'm assuming the CSV you pasted is considered properly formatted.
// HelperClass.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfCsvSkipTicker
{
public static class HelperClass
{
public static List<ItemGrid> ReadCsv(string filepath)
{
if (!File.Exists(filepath)) return null;
var allLines = File.ReadAllLines(filepath);
var result =
from line in allLines.Skip(1).Take(allLines.Length -2)
let temparry = line.Split(';')
let isSkip =
temparry.Length > 1
&& temparry[1] != null
&& temparry[1] == "X"
select new ItemGrid { ItemName = temparry[0], ItemValue = !isSkip };
return result.ToList();
}
public static void WriteCsv(IEnumerable<ItemGrid> items, string filepath)
{
var temparray = items.Select(item => item.ItemName + ";" + (item.ItemValue ? "" : "X")).ToArray();
var contents = new string[temparray.Length + 2];
Array.Copy(temparray, 0, contents, 1, temparray.Length);
contents[0] = "SFOBject;Skip";
contents[contents.Length - 1] = "SuccessMSG;";
File.WriteAllLines(filepath, contents);
}
}
public class ItemGrid
{
public string ItemName { set; get; }
public bool ItemValue { set; get; }
}
}
And...
// MainWindow.xaml.cs
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.dataGridView.ItemsSource = HelperClass.ReadCsv(#"PathToRead\configuration.csv");
}
private void btnSave_Click(object sender, RoutedEventArgs e)
{
var temp = new List<ItemGrid>();
for (int i = 0; i < this.dataGridView.Items.Count; i++)
{
if (this.dataGridView.Items[i] is ItemGrid) // DataGrid pads it's item collection with elements we didn't add.
temp.Add((ItemGrid)this.dataGridView.Items[i]);
}
HelperClass.WriteCsv(temp, #"PathToSave\new_configuration.csv");
}
}
Everything works fine until I actually call the SetPicture() Method. Any ideas as to why the image will not display when the selected item is changed. Right now i only have one image preset until i figure out my problem. Thanks for any help
namespace CelestialWindowsApp
{
public partial class Form1 : Form
{
public static List CelestialLibrary = new List(); private static CelestialBody celestialBody; private static string name; private static string description; private static string image; public static CelestialBody NewPlanet { get { return celestialBody; } set { celestialBody = value; } }
public Form1()
{
InitializeComponent();
PopulateLibrary();
}
public void PopulateLibrary()//Runs when the Form 1 is loaded. Adds preset item into the ListNox.
{
CelestialLibrary = new List<CelestialBody>();
CelestialBody cb1 = new CelestialBody("Earth", "Our Home", #"C:\Users\Cassidy\documents\visual studio 2015\Projects\CelestialWindowsApp\CelestialWindowsApp\ImageResources\earthimage.jpg");
CelestialBody cb2 = new CelestialBody("Mars", "4th planet from the sun.");
CelestialBody cb3 = new CelestialBody("Venus", "2nd planet from the son");
CelestialLibrary.Add(cb1);
CelestialLibrary.Add(cb3);
lbLibrary.DataSource = CelestialLibrary;
foreach (var p in CelestialLibrary)
{
lbLibrary.DisplayMember = "ShowBodies";
}
}
public void AddItem() // Adds the new Item to my library and then adds to and updates the ListBox;
{
CelestialBody cb;
name = txtboxName.Text;
description = txtboxDescription.Text;
image = txtboxImagePath.Text;
cb = new CelestialBody(name, description, image);
CelestialLibrary.Add(cb);
MessageBox.Show(name + " has been added to the Library.");
txtboxName.Text = null;
txtboxDescription.Text = null;
lbLibrary.DataSource = null;
lbLibrary.DataSource = CelestialLibrary;
lbLibrary.DisplayMember = "ShowBodies";
}
public void DisplayItemInfo()//Displays the current selected item information.
{
List<CelestialBody> bodyList = (List<CelestialBody>)lbLibrary.DataSource;
CelestialBody currentItem = bodyList[lbLibrary.SelectedIndex];
foreach (CelestialBody cb in bodyList)
{
if (currentItem.MyId == cb.MyId)
celestialBody = new CelestialBody(cb.Name, cb.Description, cb.ImagePath);
{
txtboxItemInfo.Text = celestialBody.Description;
SetPicture(celestialBody.ImagePath);
}
}
}
public void SetPicture(string image)
{
if (picboxBodyImage.Image != null)
{
picboxBodyImage.Image.Dispose();
}
picboxBodyImage.ImageLocation = image;
}
private void btnAddNewBody_Click(object sender, EventArgs e)
{
AddItem();
}
private void lbLibrary_SelectedIndexChanged(object sender, EventArgs e)
{
DisplayItemInfo();
}
}
}
Did you check the path in variable image. Assuming path is correct, Try below
picboxBodyImage.Image = Image.FromFile(image);
I am trying to bind a list of strings to the contents of a list box. For some reason, I get results for bluetape list, but the contents of BluetapeList does not ever make it into the listbox. Any help would be much appreciated!
XAML:
<ListBox
Name="lbxTapeIn"
Grid.Row="1"
Grid.Column="1"
Grid.ColumnSpan="1"
Width="70"
Height="80"
SelectionChanged="TapeSelectionChanged"
ItemsSource="{Binding}"
SelectedValue="{Binding SelectedBt}"
Background="DeepSkyBlue"
Foreground="MidnightBlue"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="5"/>
Code Behind:
public partial class OverrideAoiBinningWindow : Window
{
private OverrideAoiBinningWindowViewModel ovAoiBinWin;
public OverrideAoiBinningWindow()
{
InitializeComponent();
ovAoiBinWin = new OverrideAoiBinningWindowViewModel(tvwWaferList, txtFilter);
AssignDataContexts();
}
private void AssignDataContexts()
{
btnChooseWafer.DataContext = ovAoiBinWin;
btnSave.DataContext = ovAoiBinWin;
txtWafer.DataContext = ovAoiBinWin;
cbxAoiState.DataContext = ovAoiBinWin;
lbxTapeIn.DataContext = ovAoiBinWin.BluetapeList;
}
private void TapeSelectionChanged(object sender, RoutedEventArgs e)
{
if (!string.IsNullOrEmpty(ovAoiBinWin.SelectedWafer))
{
if (cbxAoiState.SelectedValue != null)
{
btnSave.IsEnabled = true;
}
}
}
private void AoiStateChanged(object sender, RoutedEventArgs e)
{
if (!string.IsNullOrEmpty(ovAoiBinWin.SelectedWafer))
{
if (lbxTapeIn.SelectedValue != null)
{
btnSave.IsEnabled = true;
}
}
}
private void Close(object sender, RoutedEventArgs e)
{
this.Close();
}
}
View Model:
public class OverrideAoiBinningWindowViewModel : ViewModelBase, ISelectWafers
{
public OverrideAoiBinningWindowViewModel(TreeView tvwWaferList, TextBox txtFilter)
{
// Set private fields
this.tvwWaferList = tvwWaferList;
this.txtFilter = txtFilter;
// Instantiate objects and initialize settings
this.InstantiateObjects();
this.SetControlSettings();
// Run the initialization thread
initThread.RunWorkerAsync();
}
public string SelectedWafer
{
get
{
return selectedWafer;
}
set
{
selectedWafer = value;
OnPropertyChanged("SelectedWafer");
}
}
public string SelectedBt
{
get
{
return selectedBt;
}
set
{
selectedBt = value;
OnPropertyChanged("SelectedBt");
}
}
public string SelectedAoiState
{
get
{
return selectedAoiState;
}
set
{
selectedAoiState = value;
OnPropertyChanged("SelectedAoiState");
}
}
public List<string> AOIStateList
{
get
{
return aoiStateList;
}
set
{
aoiStateList = value;
OnPropertyChanged("AOIStateList");
}
}
public List<string> BluetapeList
{
get
{
return bluetapeList;
}
set
{
bluetapeList = value;
OnPropertyChanged("BluetapeList");
}
}
public ICommand SelectWaferCommand
{
get
{
if (selectWaferCommand == null)
{
selectWaferCommand = new DelegateCommand(SelectWafer);
}
return selectWaferCommand;
}
}
public ICommand SaveAoiStateCommand
{
get
{
if (saveAoiStateCommand == null)
{
saveAoiStateCommand = new DelegateCommand(SaveAoiState);
}
return saveAoiStateCommand;
}
}
private void InstantiateObjects()
{
initThread = new BackgroundWorker();
aoiStateList = new List<string>();
bluetapeList = new List<string>();
converter = new WaferIDConverter();
}
private void SetControlSettings()
{
initThread.WorkerReportsProgress = false;
initThread.WorkerSupportsCancellation = false;
initThread.DoWork += InitThread_DoWork;
initThread.RunWorkerCompleted += InitThread_RunWorkerCompleted;
}
private void PopulateAoiStateList()
{
aoiStateList.Add("True");
aoiStateList.Add("False");
aoiStateList.Add("NotBinned");
aoiStateList.Add("NeverAOI");
}
private void PopulateBluetapeList()
{
waferQueries = new WaferQueries(
DataLibrary.GetSingulationOne(selectedWafer));
foreach (BlueTape tape in waferQueries.GetBlueTapeList())
{
bluetapeList.Add(tape.Name);
}
OnPropertyChanged("BluetapeList");
}
private void SaveAoiState()
{
Mouse.OverrideCursor = Cursors.Wait;
singOne = new SingOneTable();
singOne.OverrideAoiState(selectedWafer, selectedBt, selectedAoiState);
Mouse.OverrideCursor = null;
MessageBox.Show(
"The AOI state of " + selectedBt + " from " + selectedWafer +
" has been successfully changed to " + selectedAoiState + "!",
"AOI State Saved", MessageBoxButton.OK, MessageBoxImage.Exclamation);
}
public void SelectWafer()
{
Mouse.OverrideCursor = Cursors.Wait;
SelectedWafer = tvwWaferList.SelectedValue.ToString();
PopulateBluetapeList();
Mouse.OverrideCursor = null;
}
private void InitThread_DoWork(object sender, DoWorkEventArgs e)
{
if (!handled)
{
PopulateAoiStateList();
tvwPresenter = new TreeViewPresenter(tvwWaferList, txtFilter, this);
tvwPresenter.WaferList = DataLibrary.GetWaferList();
handled = true;
}
}
private void InitThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
tvwPresenter.TreeView.DataContext = tvwPresenter.ProcessesAndWafers;
tvwPresenter.WaferListCache = tvwPresenter.ProcessesAndWafers;
tvwPresenter.ProcessArray = tvwPresenter.WaferListCache.ToArray();
//TODO: Update Status text block
}
}
Answered (2nd comment) by Dilshod:
The fix was to change my List to ObservableCollection.
Once I made that change, everything worked as expected; thanks Dilshod!
Binding WPF Drop-Down control dynamically (C#).
I am using the following simple solution for binding WPF drop-down (combo-box) to a Dictionary object programmatically (C#). In this particular example Dictionary contains the list of Countries with corresponding 2-digit Country Codes (keys):
Listing 1. Dictionary object contains list of Countries w/2-digit Country codes
Dictionary<string, string> _co = new Dictionary<string, string>();
_co.Add(String.Empty, String.Empty);
_co.Add("US", "United States");
_co.Add("CA", "Canada");
_co.Add("MX", "Mexico");
Listing 2. Binding Drop-down to Dictionary object (WPF/C#)
// binding to country list Dictionary object (_co)
_cmbCountry.ItemsSource = _co;
// Country 2-digit Code used as a key
_cmbCountry.SelectedValuePath = _dKey;
// Country Name (string to display)
_cmbCountry.DisplayMemberPath = _dValue;
// first index selected
_cmbCountry.SelectedIndex = 0;
// DropDownClosed event subscription using Lambda notation
_cmbCountry.DropDownClosed += (s, e) => ComboBox_Closed(s, e);
The code snippet above (Listing 2.) also shows how to subscribe to the control event using 'short-cut' Lambda style. Hope this will help. Regards, AB
PS. You can also find more information on Drop-Down control binding techniques in my article: Binding DropDownList to various data structures in Microsoft ASP.NET