I have 2 observable collections, the idea is to load the Master Collection with all data from my database related to the form. I would filter this collection and use the filtered results to set Actor Collection. The reason im trying this is to reduce the time it takes to convert b64 image to ImageSource for larger collections. I like to convert these image only once
Onload of the form the Master Collection is populated with the items needed but when i click on a filter option, Master Collection is always 0. I can see onload 119 entries added to the collection
public ActorCollectionVM(INavigation navigation)
{
Navigation = navigation;
// one time only populate
Device.BeginInvokeOnMainThread(() =>
{
UserDialogs.Instance.ShowLoading("Loading");
Database db = new Database();
List<TMDB_Person> persons = db.GetAllPersons();
ImageUtility util = new ImageUtility();
foreach (TMDB_Person person in persons)
{
person.Profile_Thumb_Image = util.Base64ToImage(person.B64_Profile_Thumb_Image);
MasterCollection.Add(person);
}
ActorCollection = MasterCollection;
UserDialogs.Instance.HideLoading();
});
}
private void LetterSearch_Click(object sender, EventArgs args)
{
ActorCollectionVM context = (ActorCollectionVM)BindingContext;
context.ActorCollection.Clear();
Button btn = (Button)sender;
btn.TextColor = (Color)Application.Current.Resources["ThemeColor"];
if (btn.Text != "ALL")
{
foreach (TMDB_Person person in context.MasterCollection.Where(x => x.Name[0].ToString().ToLower() == btn.Text.ToLower()))
context.ActorCollection.Add(person);
}
else
{
context.ActorCollection = context.MasterCollection;
}
}
Related
I have a data grid and it is empty at first. Then I need to add items when the user selects some data. But here it shows error like
Error :
System.InvalidOperationException: Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead.
I really didn't understand what is the problem here.
I have tried datagridName.Items.clear(); and datagridName.Items.Add();. but both did't work.
private void TextboxBarCodeTextchanged(object sender,RoutedEventArgs e)
{
DataGridSalesDetails.Items.Clear();
for (int i = 0; i < AllStockList.Count; i++)
{
if (!string.IsNullOrEmpty((sender as TextBox).Text))
{
if (AllStockList[i].BarCode.StartsWith((sender as TextBox).Text,
StringComparison.InvariantCultureIgnoreCase))
{
Stock vend = AllStockList[i] as Stock;
DataGridSalesDetails.Items.Add(vend);
DataGridSalesDetails.Visibility = Visibility.Visible;
DataGridSalesDetails.Items.Refresh();
TotalReturnAmount = AllStockList.Sum(a => a.TotalAmount);
HiddenTotalAount.Text = TotalReturnAmount.ToString();
LabelFinalAmountValue.Content = TotalReturnAmount.ToString();
}
}
}
}
Expected Result is the Datagrid with added values. What I get is an error. Is there anyone to help me? I'm stuck with my project.
When working with datagrids you should assign a collection of items to the itemSource of that datagrid. Instead of assigning the collection to the itemSource, you are trying to add a new item to that datagrid.
You'll need to filter the Stock objects you are interested in and add these to a collection.
When the iteration is completed and the Stock objects are added to the collection, you'll need to assign the collection to the ItemSource.
Update from OP
The itemssource of the datagrid is bound to an Observable collection.
And OP wants to save the old list of Stock Object Items.
ObservableCollection<Stock> StockItems = new ObserveableCollection<Stock>();
private void TextboxBarCodeTextchanged(object sender,RoutedEventArgs e)
{
oldCollection = ObservableCollection;
for (int i = 0; i < AllStockList.Count; i++)
{
if (!string.IsNullOrEmpty((sender as TextBox).Text))
{
if (AllStockList[i].BarCode.StartsWith((sender as TextBox).Text,
StringComparison.InvariantCultureIgnoreCase))
{
var stock = AllStockList[i] as Stock;
StockItems.Add(stock);
}
}
}
DataGridSalesDetails.Visibility = Visibility.Visible;
TotalReturnAmount = filteredCollection.Sum(a => a.TotalAmount);
HiddenTotalAount.Text = TotalReturnAmount.ToString();
LabelFinalAmountValue.Content = TotalReturnAmount.ToString();
}
I have two tables, Equipment and Components. Each Equipment consists of 1 or more components. Right now I have a data grid showing the Equipment, with related attributes from a View in my database.
What I want is to have a second data grid in the same window, which will show the component the selected Equipment in the data grid contains.
So far I know that I can get a selected row using the SelectedItem property:
Equipment eq= (Equipment )myDataGrid.SelectedItem;
But when should this code be run? I am using EF to map my DB entities to CLR objects, where I have included the component and its relation table as well.
When the user selects a row in the Equipment, of course I would need to refresh the component data grid with the new info, which I can do like this.
myGrid.ItemsSource = myDataSource;
How can I get started on this problem?
I am using a view, that includes data from 3 different tables in my Equipment data grid, so the table set to the data grid ItemsSource does not have a direct relation with the component table.
I fixed it by using getting the components and inserted them into the data grid when the SelectionChanged event on the Equipment data grid is called:
private void EquipDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
var row_list = GetDataGridRows(EquipDataGrid);
foreach (DataGridRow single_row in row_list)
{
if (single_row.IsSelected == true)
{
EquipmentView selectedEquipment = (EquipmentView)EquipDataGrid.SelectedItem;
using (wiki_nolek_dk_dbEntities db = new wiki_nolek_dk_dbEntities())
{
db.Configuration.LazyLoadingEnabled = true;
var equipmentRelation = db.EquipmentComponents.Where(c => c.EquipmentID == selectedEquipment.EquipmentId);
var componentsForEquipment = new List<Component>();
foreach (var row in equipmentRelation)
{
var component = db.Components.FirstOrDefault(c => c.ComponentId == row.ComponentID);
componentsForEquipment.Add(component);
}
CompDataGrid.ItemsSource = componentsForEquipment;
}
}
}
}
catch
{
MessageBox.Show("Det valgte udstyr eksisterer ikke.");
}
}
I have modified your own reply's code to remove useless foreach loop.I don't know how wiki_nolek_dk_dbEntities works exactly, but I'm also adding ToList() to any db query result to make sure the result is a List and not an IQueryable.
private void EquipDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
EquipmentView selectedEquipment = (EquipmentView)EquipDataGrid.SelectedItem;
using (wiki_nolek_dk_dbEntities db = new wiki_nolek_dk_dbEntities())
{
db.Configuration.LazyLoadingEnabled = true;
var equipmentRelationComponentIds =
db.EquipmentComponents
.Where(e => e.EquipmentID == selectedEquipment.EquipmentId)
.Select(e => e.ComponentId)
.ToList();
var componentsForEquipment =
db.Components
.Where(c => equipmentRelationComponentIds.Contains(c.ComponentId))
.ToList();
CompDataGrid.ItemsSource = componentsForEquipment;
}
}
catch
{
MessageBox.Show("Det valgte udstyr eksisterer ikke.");
}
}
Please forgive me for such a stupid question. I am sure many of you will find this easy, where I have sent almost half the day reading trying to figure this out.
Here is the problem:
I have a FORM (Form1.cs) made. In that form I created a listview, and named it "ListView1".
Within the Form1.cs, I call a function called FileManager(this), where I pass in the THIS object.
In FileManager.cs I was able to listviewArray= originalForm.Controls.Find("listView1", true) and find that 'listview'.
When I do a listviewArray[0]<-- I can't seem to add a list to it.
FileManager.cs
FileManager(object sender)
{
if (sender != null)
{
originalForm = (Form)sender;
}
}
public void getFiles()
{
filePaths = Directory.GetFiles(hsocDir);
if(filePaths != null)
{
listviewArray= originalForm.Controls.Find("listView1", true);
if(listviewArray != null)
{
ListViewItem lvi = new ListViewItem("text");
// My Array is listViewArray
// How to add things to Lvi to it.
}
}
== Form1.cs
public Form1()
{
InitializeComponent(`enter code here`);
mysql = new MySQLCheck(this);
fileManager = new FileManager(this);
fileManager.getFiles();
}
You can't access element 0 of the collection because the collection is empty. To add an item, use:
listViewArray.Items.Add(lvi);
You need to modify the Items collection instead of the ListView itself for this to work, as ListView is not a collection (its a control).
listViewArray.Items.Add(lvi);
Also in your listview,setting this properties will help :
// Set the view to show details.
listViewArray.View = View.Details;
// Select the item and subitems when selection is made.
listViewArray.FullRowSelect = true;
// Display grid lines.
listViewArray.GridLines = true;
I have a method that adds items to my listbox called refreshInterface which is called as soon as the programe starts, adding names of homeforms in the listbox using the FormItems class, here is the rereshInterface method below
public void refreshInterface()
{
//int number = 0;
foreach (DataSet1.xspGetAnalysisUsageTypesRow homeForms in myDataSet.xspGetAnalysisUsageTypes)
{
var forms = new FormItems(homeForms);
listBox1.Items.Add(forms);
}
}
The FormItems class is this below
public class FormItems
{
public DataSet1.xspGetAnalysisUsageTypesRow types { get; set; }
public FormItems(DataSet1.xspGetAnalysisUsageTypesRow usageTypes)
{
types = usageTypes;
}
public override string ToString()
{
// returns the rows that are relating to types.xlib_ID
var libtyps = types.GetxAnalysisUsageRows();
var cnt = 0;
foreach (DataSet1.xAnalysisUsageRow ty in libtyps)
{
//returns true if ty is null
bool typeNull = ty.Isxanu_DefaultNull();
// if its false, if xanu_Default is set
if (!typeNull)
{
cnt += 1;
}
}
var ret = String.Format("set {0} [Set: {1}]", types.xlib_Desc, cnt);
//return this.types.xlib_Desc;
return ret;
}
}
Each listbox (the listbox is on the left of the homeform) item has a number of reports that can be added to it, so for instance, i select an homeform from my listbox, there are 12 textboxes on the right hand side and each textbox has a pair of buttons which are Browse and Clear. If I click on the browse button a new form appears, and i select a report from that form and add it to a particular textbox, the count for that homeform should update, and i clear a textbox for a particular homeform, the count should also update.
At the moment when i debug the application, it shows me the count of each Homeform depending on the amount of reports added to the homeform, but while the programe is running, if i add a new report to a homeform, the count does not update until i restart the debug session. I was told about using a Databinding method but not sure of how i could use it here
How do i ge my listbox item to update ?
You should probably look into binding. Here is a good place to start:
http://www.codeproject.com/Articles/140621/WPF-Tutorial-Concept-Binding
If you want a GUI to respond to data changes then binding is your best friend.
You should bind List Box component source to Observable Collection, every update you do to Observable Collection will update List Box data.
Might not be exact but should give you an idea.
public void refreshInterface()
{
Dictionary<int,string> items = new Dictionary<int,string>();
//int number = 0;
foreach (DataSet1.xspGetAnalysisUsageTypesRow homeForms in myDataSet.xspGetAnalysisUsageTypes)
{
var formitem = new FormItems(homeForms);
items.Add(formitem.someprop, formitem.toString());
}
listbox.DataSource = items;
listbox.DisplayMember = "Value";
listbox.ValueMember = "Key";
}
I have a ListView which I filled in from SQL Server view called view_ListaKlientow with this query:
private void fillClientsList() {
using (var context = new EntityBazaCRM()) {
var listaKlientow = from d in context.view_ListaKlientow
select d;
objectListViewListaKlientow.SetObjects(listaKlientow.ToList());
objectListViewListaKlientow.AutoResizeColumns();
}
}
Then after user double clicks one row in ListView, I read ID from the view_ListaKlientow and use fillClientGui to fill necessary fields in gui (for a test only one field is included).
private void objectListViewListaKlientow_DoubleClick(object sender, EventArgs e) {
foreach (view_ListaKlientow user in objectListViewListaKlientow.SelectedObjects) {
int id = user.KlienciID;
fillClientGui(id);
TabPageActivate(tabControlMain, tabPageKlient);
}
}
private void fillClientGui(int klientId) {
using (var context = new EntityBazaCRM()) {
IQueryable<Klienci> klient = context.Kliencis.Include("Podmioty").Where(d => d.KlienciID == klientId);
foreach (var source in klient.ToList()) {
textNIP.Text = source.Podmioty.PodmiotNIP;
}
}
}
Now I'm wondering since I know exactly I'm querying for one ID i should be getting only particular client and not a list of clients so foreach from fillClientGui just to travers IQueryable<Klienci> seems like additional unnecessary code. Or this is how it should be done? I'm trying to learn Entity and some things aren't just clear to me yet :)
If you're sure that you've got only one instance to be returned form the database, you can use the extension function FirstOrDefault() in this case:
var source = context.Kliencis.Include("Podmioty").Where(d => d.KlienciID == klientId).FirstOrDefault();
textNIP.Text = source.Podmioty.PodmiotNIP;