I have a database called Employee and I am using entity framework version 6.1.3.
In my wpf application, I have button called Search, one textbox( searchField) for search field and a datagrid ( employeedatagrid)
When i enter input in search field, it gives expected output in datagrid view but after that when i enter again different input in searchfield, it just prints the new data just below the previous data. What I want is; When i enter different search field , then If there is already data in datagrid, I want to remove those old data from datagrid and prints only the new data.
Below is my C# Code
private void Search_Click(object sender, RoutedEventArgs e)
{
this.employeeDataGrid.ItemsSource = null;
this.employeeDataGrid.Items.Clear();
var text = SearchField.Text;
var query = employeeModel.Employees.Where(x => x.Country == text).Select(y => y);
foreach (var item in query)
{
employeeDataGrid.ItemsSource = employeeModel.Employees.Local;
}
}
Can anyone point out, what I am missing here ?
thanks.
Related
I'm working on a project to develop a UWP app. I have implemented Sqlite database to store information about products.
I have a combobox in my page that displays the serial number of all the products. I've written the code for SelectionChanged event of the combobox as:
private void InvoiceSerial_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var a = conn.Query<Product>
("select brand from product where serial=?", InvoiceSerial.SelectedItem.ToString());
InvoiceBrand.Text = a.ToString();
}
But instead of displaying the brand name, I'm getting this:
System.Collections.Generic.List`1[MyProject.Inventory+Product]
InvoiceBrand is a textbox
Even if the result of an SQL query is exactly one row and one column, query functions in any language are still required to return a full table, to handle the general case where a resultant table has multiple items. The object you're looking for should be the first object in the list.
Your a variable is probably of type List<MyProject.Product>, and that's why calling a.ToString() returns the string representation of the type!
What you should probably be doing is retrieving the first element (just use a[0]) and then output the value of the "brand" field.
Ok so I got it to work thanks to #TimSchmelter
Now my code looks like this:
private void InvoiceSerial_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var a = conn.Query<Product>
("select brand from product where serial=?", InvoiceSerial.SelectedItem.ToString());
Product p = a.FirstOrDefault();
InvoiceBrand.Text = p.Brand;
}
Sorry if it has some obvious solution, but I am trying to solve it for hours but could not find a solution.
I use several ComboBoxes in my WindowsFormsApplication to relate ids with names. The problem is that when a user select an item from the combobox list, it works fine, but when he types an item, the SelectedValue property of the combobox is null.
To simulate the problem, I created a from with one button and a combobox.
In my actual application, I populate the comboboxes with data from tables in a sqlserver database, but for simplicity, here I populate it with a list:
public Form1()
{
InitializeComponent();
List<KeyValuePair<short,short>> l = new List<KeyValuePair<short,short>>();
l.Add(new KeyValuePair<short,short>(1,10));
l.Add(new KeyValuePair<short,short>(2,20));
l.Add(new KeyValuePair<short,short>(3,30));
this.comboBox1.DataSource = l;
this.comboBox1.DisplayMember = "Value";
this.comboBox1.ValueMember = "Key";
}
private void button1_Click(object sender, EventArgs e)
{
if (this.comboBox1.SelectedValue == null)
MessageBox.Show("NULL");
else
MessageBox.Show(this.comboBox1.SelectedValue.ToString());
}
For example, when user select the second item (20) from the list and clicks on the button, messagebox shows 2 as it is expected, but if he types the number 20 into the combobox, the SelectedValue is null.
This problem could be solved by changing the style of combobox:
this.comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
But it prevents user to type into the combobox, so I am forced to use the default ComboBoxStyle.DropDown.
Thats because the combo box does not select the item that you have typed. Add this option
comboBox1.AutoCompleteMode = AutoCompleteMode.Suggest;
Then it will select the item when ever it was able to find it.
By default it is set to AutoCompleteMode.None.
(I think) This is mainly designed for suggestions but it can solve your problem here. also if you want to show the suggestions:
comboBox1.AutoCompleteSource = AutoCompleteSource.ListItems;
by default it is set to AutoCompleteSource.None.
https://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.autocompletemode%28v=vs.110%29.aspx
An option that you have is using the EventHandler on the comboBox1.TextChange event that will allow you to personally handle how the text is translated into the different options.
This can be added to the designer (similar to a button).
this.comboBox1.TextChanged += new System.EventHandler(this.UpdateValue);
Then depending on how want to read the results and see if you have a match you can create a converter, use another key/value, or you can do a boring old tryparse as I will show you. You will need the list as a property that you can reference to see if you have found the proper results.
private void UpdateValue(object sender, EventArgs e)
{
short result;
if (short.TryParse(comboBox1.Text, out result))
{
var matches = from val in l where val.Value == result select val.Key;
{
foreach (short m in matches)
this.comboBox1.SelectedValue = m;
}
}
}
Good luck! Let me know if you need more examples with the event handler. Don't forget to vote.
I have an access database that contains columns such as Title, Director, And Year.
I have access database connected to the program. I am able to search the database and print out the title of the movie to a listBox only if the title contains the one word. For example, if I search for the movie "psycho" the movie will display in the listBox.
Now I'm wondering how I can search for a particular word like "the" and print all the movie titles with "the" in it to the listBox.
At that point, the text book I'm using fails to go into anything deeper.
Maybe I'm not using the right method for what I'm trying to do.
private void searchButton_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
string lowerCaseData = textBox1.Text.ToLower();
if (titleButton.Checked)
{
var query =
from m in this.moviesDataSet.Movies
where m.Title == lowerCaseData
select m;
foreach (var m in query)
{
listBox1.Items.Add(m.Title);
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'moviesDataSet.Movies' table. You can move, or remove it, as needed.
this.moviesTableAdapter.Fill(this.moviesDataSet.Movies);
}
Instead of exact match check for Contains
Depending on the LINQ provider, Contains check should be translated to SQL LIKE statement which will be case insensitive, so your check should be:
where m.Title.Contains(lowerCaseData)
However for in-memory collections, Contains would perform a case sensitive match. In that case String.IndexOf can be used like:
where m.Title.IndexOf(lowerCaseData, StringComparison.OrdinalIgnoreCase) >= 0)
Your where query is doing an exact match. Use Contains instead
where m.Title.ToLower().Contains(lowerCaseData)
How to filter a combobox based on another combobox? ... again :)
I'm writing an web app to learn. I'm using Visual Studio 2012, Silverlight 5, C#, and SQl Server for the data source.
I have one table loading into a datagrid and comboboxes to filter the datagrid. Up to this point everything is working just right.
The comboboxes are "FilterState" and "FilterWaterWay". Note they are not in the datagrid.
I want to select a state and re-populate the FilterWaterWay with only those waterways in the state.
I've seen a lot of ways to do this but none of them seem to match my setup. I could be wrong and just not know it.
From a learning standpoint, I would like to know how to implement this in all 3 of the following query data examples but I'll settle for just one. The last one is my favorite.
Thanks for any and all help.
I would not mind using the following to load comboboxes, filtered or not, but I can't firgure out how to
Restirct the GetQuery to only one field
Make that field distinct
This loads all data from the GetQuery to the datagrid.
LoadOperation<MASTER_DOCKS> loadOp = this._DocksContext.Load(this._DocksContext.GetMASTER_DOCKSQuery());
DocksGrid.ItemsSource = loadOp.Entities;
This loads all data from the GetQuery to the datagrid after it's been filtered
EntityQuery<MASTER_DOCKS> query = _DocksContext.GetMASTER_DOCKSQuery();
query = query.Where(s => s.WTWY_NAME == WaterwaytoFilterBy && s.STATE == StateToFilterBy);
LoadOperation<MASTER_DOCKS> loadOp = this._DocksContext.Load(query);
DocksGrid.ItemsSource = loadOp.Entities;
This is how I am currently loading the comboboxes. This works fine for the load but I don't see how to filter.
The DomainService.cs does not know my other combobox (FilterState) that I want to use as the filter for this combobox (FilterWaterway).
If I could query the ObservableCollection in the xaml I might be able to get it to work but it seems kind of chunky.
Adapted from http://www.jonathanwax.com/2010/10/wcf-ria-services-datagrid-filters-no-domaindatasource-2/
XAML =
private ObservableCollection<string> waterWayFilterList;
public ObservableCollection<string> WaterWayFilterList
{
get { return waterWayFilterList; }
set { waterWayFilterList = value; }
}
private void DoPopulateFilter()
{
//Call Invoke Method to get a list of distinct WaterWays
InvokeOperation<IEnumerable<string>> invokeOp = _DocksContext.FillWaterWayList();
invokeOp.Completed += (s, e) =>
{
if (invokeOp.HasError)
{
MessageBox.Show("Failed to Load Category Filter");
}
else
{
//Populate Filter DataSource
WaterWayFilterList = new ObservableCollection<string>(invokeOp.Value);
//Add a Default "[Select]" value
WaterWayFilterList.Insert(0, "[Select WaterWay]");
FilterWaterWay.ItemsSource = WaterWayFilterList;
FilterWaterWay.SelectedItem = "[Select WaterWay]";
}
};
}
DomainService.cs =
[Invoke]
public List<string> FillWaterWayList()
{
return (from r in ObjectContext.MASTER_DOCKS
select r.WTWY_NAME).Distinct().ToList();
}
Here's the closest I've gotten so far and it seems straight forward.
It returns no errors but the displayed result reads System.Collections.Generic.List'1[System.Char]
The record count in the dropdown is correct which leads me to think it's on the right track.
Only what is displayed is wrong. A casting problem perhaps?
I would still have to get the result from the FilterState Combo box in where "TX" is.
var filter = from r in _DocksContext.MASTER_DOCKS
where r.STATE.Equals("TX")
select r.WTWY_NAME.Distinct().ToList();
MyComboBox.ItemsSource = filter;
Without parentheses, you're doing the .Distinct().ToList() on the string (which implements IEnumerable<char>, which is why those operations work), which results in a List<char> (which isn't what you're looking for). You need to add parentheses so you get the distinct waterways:
var filter = (from r in _DocksContext.MASTER_DOCKS
where r.STATE.Equals("TX")
select r.WTWY_NAME).Distinct().ToList();
Note that if two waterways might have the same name, but actually be distinct, you'll need to instead select distinct r, and then differentiate them in the dropdown somehow, e.g.
var filter = (from r in _DocksContext.MASTER_DOCKS
where r.STATE.Equals("TX")
select r).Distinct().ToList();
// generated classes are partial, so you can extend them in a separate file
public partial class MASTER_DOCKS
{
// the dropdown uses the ToString method to show the object
public override string ToString()
{
return string.Format("{0} ({1})", WTWY_NAME, ID);
}
}
I'm reading a text file line by line, and inserting it into an array.
I then have this list called custIndex, which contains certain indices, indices of the items array that I'm testing to see if they are valid codes. (for example, custIndex[0]=7, so I check the value in items[7-1] to see if its valid, in the two dictionaries I have here). Then, if there's an invalid code, I add the line (the items array) to dataGridView1.
The thing is, some of the columns in dataGridView1 are Combo Box Columns, so the user can select a correct value. When I try adding the items array, I get an exception: "The following exception occurred in the DataGridView: System.ArgumentException: DataGridViewComboBoxCell value is not valid."
I know the combo box was added correctly with the correct data source, since if I just add a few items in the items array to the dataGridView1, like just items[0], the combo box shows up fine and there's no exception thrown. I guess the problem is when I try adding the incorrect value in the items array to the dataGridView1 row.
I'm not sure how to deal with this. Is there a way I can add all of the items in items except for that value? Or can I add the value from items and have it show up in the combo box cell, along with the populated drop down items?
if(choosenFile.Contains("Cust"))
{
var lines = File.ReadAllLines(path+"\\"+ choosenFile);
foreach (string line in lines)
{
errorCounter = 0;
string[] items = line.Split('\t').ToArray();
for (int i = 0; i <custIndex.Count; i++)
{
int index = custIndex[i];
/*Get the state and country codes from the files using the correct indices*/
Globals.Code = items[index - 1].ToUpper();
if (!CountryList.ContainsKey(Globals.Code) && !StateList.ContainsKey(Globals.Code))
{
errorCounter++;
dataGridView1.Rows.Add(items);
}
}//inner for
if (errorCounter == 0)
dataGridView2.Rows.Add(items);
}//inner for each
}//if file is a customer file
Say your text file contains:
Australia PNG, India Africa
Austria Bali Indonisia
France England,Scotland,Ireland Greenland
Germany Bahama Hawaii
Greece Columbia,Mexico,Peru Argentina
New Zealand Russia USA
And lets say your DataGridView is setup with 3 columns, the 2nd being a combobox.
When you populate the grid and incorrectly populate the combobox column you will get the error.
The way to solve it is by "handling/declaring explicitly" the DataError event and more importantly populating the combobox column correctly.
private void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
//Cancelling doesn't make a difference, specifying the event avoids the prompt
e.Cancel = true;
}
private void dataGridView2_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
e.Cancel = true;
}
So imagine the 2nd column contained a dropdownlist of countries and the 1st & 3rd column contained text fields.
For the 1st and 3rd columns they are just strings so I create a class to represent each row:
public class CountryData
{
public string FirstCountry { get; set; }
public string ThirdCountry { get; set; }
}
For the 2nd column "Countries" combobox cell's I have created a separate class because I will bind it to the 2nd columns datasource.
public class MultiCountryData
{
public string[] SeceondCountryOption { get; set; }
}
Populating the grid with combobox columns and the like as shown here: https://stackoverflow.com/a/1292847/495455 is not good practice. You want to separate your business logic from your presentation for a more encapsulated, polymorphic and abstract approach that will ease unit testing and maintenance. Hence the DataBinding.
Here is the code:
namespace BusLogic
{
public class ProcessFiles
{
internal List<CountryData> CountryDataList = new List<CountryData>();
internal List<MultiCountryData> MultiCountryDataList = new List<MultiCountryData>();
internal void foo(string path,string choosenFile)
{
var custIndex = new List<int>();
//if (choosenFile.Contains("Cust"))
//{
var lines = File.ReadAllLines(path + "\\" + choosenFile);
foreach (string line in lines)
{
int errorCounter = 0;
string[] items = line.Split('\t');
//Put all your logic back here...
if (errorCounter == 0)
{
var countryData = new CountryData()
{
FirstCountry = items[0],
ThirdCountry = items[2]
};
countryDataList.Add(countryData);
multiCountryDataList.Add( new MultiCountryData() { SeceondCountryOption = items[1].Split(',')});
}
//}
}
}
}
In your presentation project here is the button click code:
imports BusLogic;
private void button1_Click(object sender, EventArgs e)
{
var pf = new ProcessFiles();
pf.foo(#"C:\temp","countries.txt");
dataGridView2.AutoGenerateColumns = false;
dataGridView2.DataSource = pf.CountryDataList;
multiCountryDataBindingSource.DataSource = pf.MultiCountryDataList;
}
I set dataGridView2.AutoGenerateColumns = false; because I have added the 3 columns during design time; 1st text column, 2nd combobox column and 3rd text column.
The trick with binding the 2nd combobox column is a BindingSource. In design time > right click on the DataGridView > choose Edit Columns > select the second column > choose DataSource > click Add Project DataSource > choose Object > then tick the multiCountry class and click Finish.
Also set the 1st column's DataPropertyName to FirstCountry and the 3rd column's DataPropertyName to ThirdCountry, so when you bind the data the mapping is done automatically.
Finally, dont forget to set the BindingSource's DataMember property to the multiCountry class's SeceondCountryOption member.
Here is a code demo http://temp-share.com/show/HKdPSzU1A