I'm writing a simple first app using Winforms, C#, VS2010, and Entity Framework. Basically, I have a rich DB I'm tapping, and I've already set up the framework, successfully enough to populate a DataGridView control with a subset of the Work Order table.
Now, I want to place a combo box on the form ("cbProjectID") whose value is ProjectID and DisplayValue is ProjectNbr. I only want to put projects in the combo box list that are related to WorkOrders, and only unique ProjectIDs within that set (a project may have dozens of work orders....)
I'm assuming I need to generate a list from EF, using LINQ. I'm pretty new at LINQ, and I'm not figuring it out...Here's my code so far...
using System;
using CPASEntityFramework;
using System.Data.Entity;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace BrowseWorkOrders
{
public partial class BrowseWOs : Form
{
public BrowseWOs()
{
InitializeComponent();
}
private void BrowseWOs_Load(object sender, EventArgs e)
{
var context = new CPASEntities();
var query = context.tblWorkOrders.Where(c => c.ProjectID==8);
tblWorkOrderBindingSource.DataSource = query.ToList();
// Now, I want to load up the Combo Box with all the projects in the Work Order Table
}
}
}
I've been through the net trying to find a method I understand, but I'm failing. Perhaps someone can help me out. Here's my Datasource (I assume I should NOT use tblProject, but instead use the tblProject inside tblWorkOrder in order to get my subset...)
Any help and/or guidance would be appreciated.
Here's the code now...
namespace BrowseWorkOrders
{
public partial class BrowseWOs : Form
{
public BrowseWOs()
{
InitializeComponent();
}
private void BrowseWOs_Load(object sender, EventArgs e)
{
// Following loads up all Projects into the cbProjectID Combo Box
var context = new CPASEntities();
var PrID = context.qryProjectIDNbrDescs.ToList();
cbProjectID.DataSource = PrID;
cbProjectID.ValueMember = "ID";
cbProjectID.DisplayMember = "ProjectNbr";
}
private void cbProjectID_SelectedIndexChanged(object sender, EventArgs e)
{
var context = new CPASEntities();
var query = context.tblWorkOrders.Where(c => c.ProjectID == (int)cbProjectID.SelectedValue).ToList();
tblWorkOrderBindingSource.DataSource = query;
}
}
}
You need the tblProject on the top because the other is for a single WorkOrder only. However, you need to filter the list with those who have at least on WorkOrder:
var projects = context.tblProjects.Where(p => p.tblWorkOrders.Any()).ToArray();
cbProjectID.DataSource = projects;
cbProjectID.ValueMember = "ProjectID";
cbProjectID.DisplayMember = "ProjectNbr";
Related
hi im sorta new to doing projects myself but one of my first tasks was to make a btec grade to ucas points converter by allowing the user to select their grade from the combobox and it would show in a label the correlating grade
however i dont know how to get the selected combobox item to change the label for each different grade
i tried using a an if statement but i realised that it comes up with error CS0029
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace btec_to_ucas
{
public partial class Form1 : Form
{
string PPP = "48";
string MPP = "64";
string MMP = "80";
string MMM = "96";
string MMD = "112";
string DDM = "128";
string DDD = "144";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (comboBox1 = PPP)
{
label1.Text = PPP;
}
}
}
}```
Problem is here: if (comboBox1 = PPP). In this case, comboBox1 is the whole combo box object, with its items, selected index, size, etc. That will never be equal to the string "48". You want to look at the value that has been entered. Try comboBox1.SelectedText.
See:
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.combobox?view=netcore-3.1
I have a custom combobox control that is supposed to show a list of webcams available.
The code is fairly tiny.
using System;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Windows.Forms;
using DirectShowLib;
namespace CameraSelectionCB
{
public partial class CameraComboBox : ComboBox
{
protected BindingList<string> Names;
protected DsDevice[] Devices;
public CameraComboBox()
{
InitializeComponent();
Devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
Names = new BindingList<string>(Devices.Select(d => d.Name).ToList());
this.DataSource = Names;
this.DropDownStyle = ComboBoxStyle.DropDownList;
}
}
}
However, I ran into a couple of bugs.
First, whenever I place an instance of this combobox, designer generates the following code:
this.cameraComboBox1.DataSource = ((object)(resources.GetObject("cameraComboBox1.DataSource")));
this.cameraComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cameraComboBox1.Items.AddRange(new object[] {
"HP Webcam"});
Which results in an exception during runtime, since Items should not be modified when DataSource is set. This happens even if I don't touch Items property in the designer.
"HP Webcam" is the only camera present on my computer at the time.
How can I suppress this behaviour?
When you drop your control on a form the constructor code and any loading code will run. Any code in there that changes a property value will be executed in designtime and therefore will be written in the designer.cs of the form you dropped your control on.
When programming controls you should always keep that in mind.
I solved this by adding a property that I can use to check if the code executed in designtime or runtime.
protected bool IsInDesignMode
{
get { return DesignMode || LicenseManager.UsageMode == LicenseUsageMode.Designtime; }
}
protected BindingList<string> Names;
protected DsDevice[] Devices;
public CameraComboBox()
{
InitializeComponent();
if (InDesignMode == false)
{
// only do this at runtime, never at designtime...
Devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
Names = new BindingList<string>(Devices.Select(d => d.Name).ToList());
this.DataSource = Names;
}
this.DropDownStyle = ComboBoxStyle.DropDownList;
}
Now the binding will only happen at runtime
Dont forget to remove the generated code in the Designer.cs file when you try this
The problem is that the binding in constructor is being run by the designer. You could try moving it to the Initialise or Loaded events
I added 3 items to the comboBox in the form, using the Items property. These items are: Item1, Item2, Item3.
When I select any of these 3 items in the comboBox, I want it to show a messagebox that contains the value of the first attribute of the corresponding object.
For example when i click Item1, I want it to show me attribute "CNP1" from object a1, when I click Item2, to show me attribute CNP2 from object a2 and so on.
I think that I might connect each item in the comboBox with one of the 3 object created, not just write down these names(Item1,Item2,Item3) but I don't know how.
Also, these 3 items are created due to a class I created in the same project.
I only have a class, a form and the main Program in this project.
So, how can I connect a comboBox Item to one of these objects, especially with only one attribute of that object. Thank you.
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace IncercareEX2015
{
public partial class PreluareDate : Form
{
ArrayList listaAbonati;
AbonatTelefonic ab;
public PreluareDate()
{
InitializeComponent();
double[] vectMin = new double[4] { 12, 15, 50, 20 };
AbonatTelefonic a1 = new AbonatTelefonic("CNP1", "Nume1", "Adresa1", "tel1", "tip1", vectMin);
double[] vectMin3 = new double[2] { 100, 130 };
AbonatTelefonic a3 = new AbonatTelefonic("CNP3", "Nume3", "Adresa3", "Tel3", "Tip3", vectMin3);
double[] vectMin2 = new double[3] { 200, 80, 150 };
AbonatTelefonic a2 = new AbonatTelefonic("CNP2", "Nume2", "Adresa2", "Tel2", "Tip2", vectMin2);
///GENERARE COLECTIE DE OBIECTE
ArrayList listaAbonati = new ArrayList();
listaAbonati.Add(a1);
listaAbonati.Add(a3);
listaAbonati.Add(a2);
listaAbonati.Sort();
}
private void comboBox1_nume_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (object o in listaAbonati)
MessageBox.Show(o.ToString());
}
}
}
Assuming that your code compiles and shows the o.ToString() when the selected index changes you would want to switch from using an ArrayList to a generic List, in your case a List which will allow you to access the properties of your entities without the need to casting in the event handler. Here's the relevant portion of your code:
List<AbonatTelefonic> listaAbonati;
public PreluareDate()
{
///GENERARE COLECTIE DE OBIECTE
listaAbonati = new List<AbonatTelefonic>();
listaAbonati.Add(a1);
listaAbonati.Add(a3);
listaAbonati.Add(a2);
listaAbonati.Sort();
}
private void comboBox1_nume_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (AbonatTelefonic at in listaAbonati)
MessageBox.Show(at.YourDesiredPropertyNameGoesHere);
}
You can use SelectedIndex to get AbonatTelefonic. I hope it will help you.
private void comboBox1_nume_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1_nume.SelectedIndex != -1)
{
AbonatTelefonic at = (AbonatTelefonic)listaAbonati[comboBox1_nume.SelectedIndex];
MessageBox.Show(at.YourAttribute);
}
}
Add public override string ToString() on your AbonatTelefonic class and add the code return {first attrib variable};
Reference for you: https://msdn.microsoft.com/en-us/library/ms173154(v=vs.80).aspx
Hope this helps.
I have a situation where I have to disable certain controls on database value change.
For that I have used following code.
Here I am disabling the controls in the panel on 0 value and on any other values I am enabling it.
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class test_control : System.Web.UI.Page
{
string test1;
List<double> _data = new List<double>();
public DataTable dt = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
GetData();
}
private void GetData()
{
int maxId;
using (SqlConnection dataConnection = new SqlConnection("Data Source=localhost\\SQLEXPRESS;Initial Catalog=MCAS;Integrated Security=SSPI"))
using (SqlCommand dataCommand =
new SqlCommand("select top 1 RunMode from MCASMonitoring_Rev1 order by Id desc", dataConnection))
{
dataConnection.Open();
maxId = Convert.ToInt32(dataCommand.ExecuteScalar());
TextBox1.Text = maxId.ToString();
if (TextBox1.value == 0)
{
Panel1.Enabled = false;
}
else
{
Panel1.Enabled = true;
}
}
}
}
But the situation is that I have to refresh the page to achieve this operation. But What I want is that I need it in runtime without refreshing the entire page.
SnPandya....
Suggestion 1
Panels should be disable based on DB values...So definitely once you have to come across server side.
Now, once you have DB values then you can call javascript from serverside and disable any controls you want........
Suggestion 2
Put your controls inside "Updatepanel" then you will not feel any page postback
I am getting a error for my namespace that says " the type or namespace name could not be found (are you missing a using directive or an assembly reference?) " and have no idea why... i have been trying to figure this one out for hours now... btw i am a newbie with c#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using portfolioNamespace;
public partial class DefaultCode : System.Web.UI.Page{
Portfolio myPortfolio;
protected void Page_Load(object sender, EventArgs e){
//declare
myPortfolio = new Portfolio();
populate();
}
private void populate(){
//populate everything
populateMenu();
populateHome();
populateSamples();
populateAbout();
}
private void populateMenu(){
//populate the menu
String[] menu;
menu = myPortfolio.getMyMenu();
repLinks.DataSource = menu;
repLinks.DataBind();
//populates a hidden text box so i can get an array in javascript
for (int i = 0; i<=menu.Length - 1; i++){
dummy.Value = dummy.Value & menu(i) & "-";
}
}
private void populateHome(){
//populate home
homeRepeater.DataSource = myPortfolio.getHomeInfo;
homeRepeater.DataBind();
}
private void populateSamples(){
//populate samples
samplesRepeater.DataSource = myPortfolio.getSamplesInfo;
samplesRepeater.DataBind();
}
private void populateAbout(){
//populate about
aboutRepeater.DataSource = myPortfolio.getAboutInfo;
aboutRepeater.DataBind();
}
}
In your Solution Explorer Right click your References, click Add Reference > Browse, then find your dll file that contains portfolioNamespace and add it to your References.
See documentation for more details: How to: Add or Remove References By Using the Add Reference Dialog Box
You probably haven't created the portfolioNamespace.
You do so by wrapping your code in
namespace portfolioNamespace
{
//your code here
}
Have a read through these references, namespace (C# Reference) and Namespaces (C# Programming Guide)
It is not clear which file is getting error.
whatever the class name is giving error put cursor on that and press CTRL + DOT(.) it will suggest you to add the correct name space