I am databind Listbox in MVVM pattern,I am using Entity Framework for getting data,this is how I am doing
XAML:
<ListBox Margin="0,26,860,-146" x:Name="lstuser" ItemsSource="{Binding ListBoxDS}"/>
C# code:
private ObservableCollection<Users> _lstusers;
public ObservableCollection<Users> ListBoxDS
{
get
{
if (_lstusers == null)
{
_lstusers = new ObservableCollection<Users>();
}
return _lstusers;
}
set
{
_lstusers = value;
NotifyOfPropertyChange("ListBoxDS");
}
}
public class Users
{
public int UserID { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
}
DataContext:
public static IList<Users> GetAllUsers
{
try
{
using (var context = new ApplicationContext())
{
return context.UsersInfo.ToList();
}
}
finally
{
}
}
and in my ViewModel
var allusersList=GetAllUsers();
var users = allusersList.Where(a => a.FirstName =="some value").ToList();
foreach (var item in users)
{
_lstusers.Add(new Users { UserID = item.Id, UserName = item.Username,FirstName=item.firstname });
}
When I am ruuning my project,its not showing any item in Listbox, I am following this link
I have debugged it, data is appearing in ListDS.
in your code i cant see that you add the item to your list. it should be
var users = allusersList.Where(a => a.FirstName =="some value").ToList();
foreach (var item in users)
{
ListBoxDS.Add(new Users { UserID = item.Id, UserName = item.Username,FirstName=item.firstname });
}
EDIT: then your code should work if you set the right DataContext. you can check this with Snoop at runtime.
Related
I'm developing a web browser in C# using Visual Studio 2017. I am trying to save the user's search history in a database and display it in a listbox. However, the database and listbox are empty. I have no idea why it's not working.
I have a bookmark button that works in the same way. It functions fine. The bookmarks show up in the listbox.
Any thoughts as to why the history listbox is always empty?
public class HistoryItem
{
public string URL { get; set; }
public string Title { get; set; }
public DateTime Date { get; set; }
public int Id { get; set; }
}
public static void AddItem(HistoryItem item)
{
var adapter = new HistoryTableAdapter();
adapter.Insert(item.URL, item.Title, item.Date.ToShortDateString());
}
public static List<HistoryItem> GetItems()
{
var adapter = new HistoryTableAdapter();
var results = new List<HistoryItem>();
var rows = adapter.GetData();
foreach (var row in rows)
{
var item = new HistoryItem();
item.URL = row.URL;
item.Title = row.Title;
item.Date = DateTime.Parse(row.Date);
item.Id = row.Id;
results.Add(item);
}
return results;
}
private void DisplayLabel(object sender, WebBrowserDocumentCompletedEventArgs e)
{
toolStripStatusLabel1.Text = "Done";
toolStripProgressBar1.Value = 0;
var item = new HistoryItem();
item.URL = toolStripTextBox1.Text;
item.Title = webBrowser1.DocumentTitle;
item.Date = DateTime.Now;
HistoryManager.AddItem(item);
}
private void HistoryManager_Load(object sender, EventArts e)
{
var items = HistoryManager.GetItems();
foreach (var item in items)
{
HistoryListBox.Items.Add(string.Format("{0} ({1}) [{2}]", item.Title, item.URL, item.Date));
}
}
I wanted to know what is the first item that was checked on a checkbox,
Here is my code to know what are the selected item, but I do not know how to know the first item that was checked.
private List<VehicleOptionalEquipment> SelectedEngineOptions(long vehicleId, int? styleId, List<VehicleOptionalEquipment> optionalEquips)
{
var optionEngine = new List<VehicleOptionalEquipment>();
foreach (var optionalEquip in optionalEquips)
{
if (optionalEquip.TypeId == (int)OptionSectionEnum.ENGINE)
{
if (optionalEquip.IsSelected == true)
{
var engineSelected = new VehicleOptionalEquipment
{
TypeId = optionalEquip.TypeId,
Index = optionalEquip.Index,
IsSelected = optionalEquip.IsSelected
};
optionEngine.Add(engineSelected);
}
else
{
var engineNotSelected = new VehicleOptionalEquipment
{
TypeId = optionalEquip.TypeId,
Index = optionalEquip.Index,
IsSelected = optionalEquip.IsSelected
};
optionEngine.Remove(engineNotSelected);
}
}
}
return optionEngine;
}
}
Here is my model:
public class VehicleOptionalEquipment
{
public int TypeId { get; set; }
public int Index { get; set; }
public bool IsSelected { get; set; }
}
Instead of foreach loop and if conditions, you can achieve it in LINQ
var optionEngine = optionalEquips.Where(x => x.TypeId == (int)OptionSectionEnum.ENGINE &&
x.IsSelected).ToList();
You can get the engine type and IsSelected true records to the optionEngine.
I have a list with Strings of Display names of Model:
public class TVSystemViewData : BaseViewData
{
[Display(Name = "AccountId", Description = "")]
public String AccountId { get; set; }
[Display(Name = "AllocatedManagedMemory", Description = "")]
public String AllocatedManagedMemory { get; set; }
[Display(Name = "AllocatedPhysicalMemory", Description = "")]
public String AllocatedPhysicalMemory { get; set; }
[Display(Name = "AudioMute", Description = "")]
public String AudioMute { get; set; }
}
I need to set the properties with a foreach loop to add the values to my Model:
This is how get values from POST the application
var model.AccountId = shell.getParameter("AccountId")
var model.AllocatedManagedMemory = shell.getParameter("AllocatedManagedMemory");
The shell.GetParameter get the value from a POST.
this is how i want:
I have a a Method to get all Display attr
public List<String> GetTVSystemProperties()
{
return typeof(TVSystemViewData)
.GetProperties()
.SelectMany(x => x.GetCustomAttributes(typeof(DisplayAttribute), true) //select many because can have multiple attributes
.Select(e => ((DisplayAttribute)e))) //change type from generic attribute to DisplayAttribute
.Where(x => x != null).Select(x => x.Name) //select not null and take only name
.ToList();
}
My collection is a list of Strings
ex: collection {"AccountId","AllocatedManagedMemory"...}
My model is TVSystemViewData
foreach (item in collection)
{
if(item == modelProperty name){
// i don know how
model.property = shell.getParameter(item)
}
}
[UPDATED]
I am using this:
foreach (var property in UtilsHandler.getConfigAsList("sysDataSource"))
{
//Set Values to Model
try
{
model.GetType().GetProperty(property).SetValue(model, shell.getParameter(property), null);
}
catch (Exception)
{
Have issue with data types
}
}
I have issues with data types.
But i use one foreach loop.
Still looking for a best method
you need to make the class inherit from IEnumerator, or add a GetEnumerator method yourself.
var model = new TVSystemViewData();
foreach(var item in model)
{
item.AccountId = shell.getParameter("AccountId");
//item.AllocatedManagedMemory ...
}
Please refer to this post for more information : How to make the class as an IEnumerable in C#?
Check this article out: https://support.microsoft.com/en-us/help/322022/how-to-make-a-visual-c-class-usable-in-a-foreach-statement
//EDIT. Forgot this part :
List<TVSystemViewData> model;
[Display(Name = "AccountId", Description = "")]
public String AccountId { get; set; }
[Display(Name = "AllocatedManagedMemory", Description = "")]
public String AllocatedManagedMemory { get; set; }
[Display(Name = "AllocatedPhysicalMemory", Description = "")]
public String AllocatedPhysicalMemory { get; set; }
[Display(Name = "AudioMute", Description = "")]
public String AudioMute { get; set; }
public IEnumerator<TVSystemViewData> GetEnumerator()
{
foreach (var item in model)
{
yield return item;
}
}
EDIT According to your update question: I don't know if this is the way to go but it should work.
var model = new TVSystemViewData();
PropertyInfo[] properties = typeof(TVSystemViewData).GetProperties();
List<string> items = new List<string> { "AccountId", "AllocatedManagedMemory" }; //your collection of strings
foreach (var item in items)
{
foreach (var property in properties)
{
if (item == property.Name)
{
property.SetValue(model, shell.getParameter(item));
}
}
}
I am working on Sales App of Windows Store app. I want to apply lazy loading for my product module.
When Product page open it get product from backend and show in ListBox control.
It takes time everytime to load. I think main reason is when I check for the image exists on given url.
Here is my code and class:
private async Task getAllProductDetails()
{
var resultproductlist = await client.PostAsync(session.Values["URL"] + "/magemobpos/product/getProductList", contents);
if (resultproductlist.IsSuccessStatusCode)
{
string trys = resultproductlist.Content.ReadAsStringAsync().Result;
List<Productlistdata> objProducts = JsonConvert.DeserializeObject<ProductlistResponse>(trys).productlistdata;
Productlistdata Product;
//all product are in objProducts
foreach (var item in objProducts)
{
bool imageexist = false;
//check if image exist on given url or not
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(item.image.ToString()));
using (var response = (HttpWebResponse)(await Task<WebResponse>.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null)))
{
int imagelength = Convert.ToInt32(response.ContentLength);
if (imagelength > 0)
imageexist = true;
else
imageexist = false;
}
}
catch (Exception)
{
imageexist = false;
}
//if image not exist, it get default image
if (item.image.ToString().ToLower().Equals("n/a") || imageexist == false)
{
item.image = "Images/NoDataImages/ico-no-orders.png";
}
Product = new Productlistdata()
{
image = item.image,
name = item.name,
price = item.price,
sku = item.sku,
type = item.type[0],
id = item.id
};
//add all product in lstProduct. lstProduct is ListBox Control
lstProduct.Items.Add(Product);
}
}
}
Class:
public class Productlistdata
{
public string id { get; set; }
public string sku { get; set; }
public string name { get; set; }
public string status { get; set; }
public string qty { get; set; }
public string price { get; set; }
public string image { get; set; }
public string type { get; set; }
public string full_productname { get; set; }
}
Can anybody suggest me how to apply lazy loading? I don't know exactly but I think it can apply to bind image once the list is loaded.
I know that you dint ask for it but I ll strongly suggest you to look into Bindings I believe it will help you a lot thinking what you are trying to build. So I ll start by changing some of your code using bindings and then go to the real solution.
Here is what you can try and do:
First remove this code:
bool imageexist = false;
//check if image exist on given url or not
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(item.image.ToString()));
using (var response = (HttpWebResponse)(await Task<WebResponse>.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null)))
{
int imagelength = Convert.ToInt32(response.ContentLength);
if (imagelength > 0)
imageexist = true;
else
imageexist = false;
}
}
catch (Exception)
{
imageexist = false;
}
Second Step is to get rid of this code
//add all product in lstProduct. lstProduct is ListBox Control
lstProduct.Items.Add(Product);
Now add on top of you page.xaml.cs an ObservableCollection
private ObservableCollection<Productlistdata> productlist = new ObservableCollection<Productlistdata>();
public ObservableCollection<Productlistdata> Productlist
{
get { return productlist ?? (productlist= new ObservableCollection<Productlistdata>()); }
set { productlist= value; }
}
Now you either bind that list in the list box like this
<ListBox ItemsSource="{Binding Productlist}"/>
or In the Contractor of your page do
lstProduct.ItemsSource = Productlist;
That way Productlist is binded to your ListBox and when you add or remove items will it will be updated automatically.
Now you can skip all the above but I suggest you to look into Bindings it powerfull and will solve many of your problems when you get the idea of they work.
Now we will add the first code we removed in your ProductListdata
public class Productlistdata
{
public string id { get; set; }
public string sku { get; set; }
public string name { get; set; }
public string status { get; set; }
public string qty { get; set; }
public string price { get; set; }
public string image { get; set; }
public string type { get; set; }
public string full_productname { get; set; }
public async void CheckImage()
{
bool imageexist = false;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(image));
using (var response = (HttpWebResponse)(await Task<WebResponse>.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null)))
{
int imagelength = Convert.ToInt32(response.ContentLength);
if (imagelength > 0)
imageexist = true;
else
imageexist = false;
}
}
catch (Exception)
{
imageexist = false;
}
if (!imageexist)
{
image = "Images/NoDataImages/ico-no-orders.png";
}
}
}
And populate your List
private async Task getAllProductDetails()
{
var resultproductlist = await client.PostAsync(session.Values["URL"] + "/magemobpos/product/getProductList", contents);
if (resultproductlist.IsSuccessStatusCode)
{
string trys = resultproductlist.Content.ReadAsStringAsync().Result;
List<Productlistdata> objProducts = JsonConvert.DeserializeObject<ProductlistResponse>(trys).productlistdata;
//all product are in objProducts
foreach (var item in objProducts)
{
Productlistdata Product = new Productlistdata()
{
image = item.image,
name = item.name,
price = item.price,
sku = item.sku,
type = item.type[0],
id = item.id
};
Product.CheckImage();
Productlist.Add(Product);
}
}
}
Product.CheckImage(); will not be awaited. So the Items in the list will load really fast because nothing is awaited in the foreach loop. Product.CheckImage(); will run on another thread at later time.
Finally because image might change after the data is loaded on the ListBoxa(when image wasnt fount) you will have to Notify the UI that a property has changed. To do that you will have to use INotifyPropertyChanged. You can take a look in an other answer of mine how to do that here
I would suggest changing your queries,
firstly instead of getAllProductDetails do getAllProductID
so where you have
var resultproductlist = await client.PostAsync(session.Values["URL"] + "/magemobpos/product/getProductList", contents);
if (resultproductlist.IsSuccessStatusCode)
{
string trys = resultproductlist.Content.ReadAsStringAsync().Result;
List<Productlistdata> objProducts = JsonConvert.DeserializeObject<ProductlistResponse>(trys).productlistdata;
Productlistdata Product;
you would do
var resultproductlist = await client.PostAsync(session.Values["URL"] + "/magemobpos/product/getProductID", contents);
if (resultproductlist.IsSuccessStatusCode)
{
string trys = resultproductlist.Content.ReadAsStringAsync().Result;
List<int> objProducts = JsonConvert.DeserializeObject<ProductlistResponse>(trys).productlistdata;
LazyProductlistdata Product;
secondly create a wrapper
public LazyProductlistdata
{
public string id { get; set; }
private Lazy<Productlistdata> data = new Lazy<Productlistdata>(()=>Productlistdata.CreateFromID(id));
public Productlistdata Data
{
get{return data.Value;}
}
}
expand this so the wrapper contains information required for sorting
finally alter the constructor or create a factory for Productlistdata so that it obtains the individual record from the source
public class Productlistdata
{
public static Productlistdata CreateFromID(int id)
{
//Return single Productlistdata from webservice
}
}
NOTE: lazy loading will increase the overall load time, the advantange is that instead of it being 1 huge block of time its several smaller ones
I would suggest using Converter to supply placeholder see here.
You can also decorate Image.Source binding with IsAsync = True - so that main thread would not be blocked
You can use ImageFailed event to assign image placeholder
foreach (var item in objProducts)
{
var bitmap = new BitmapImage();
bitmap.ImageFailed += (s, e) => bitmap.UriSource = defaultImageUri;
bitmap.UriSource = new Uri(item.image);
item.Add(bitmap);
//set decodepixelwidth and dicodepixelheight correctly to avoid outofmemory exception
}
I am trying to understand how to implement a treeview control - it all looks hideously complicated. However, the Treeview control would be more appropriate.
I have an SQL table containing fields ID and ParentLevelID.
I have added a basic Treeview control to my code:
<asp:TreeView ID="tvLevels" runat="server">
</asp:TreeView>
I want to populate this table using LinqToSQL. Presently, I am displaying the same data as a Gridview:
protected void SetupLevelsPanel()
{
// display levels according to current parentId
_svsCentralDataContext = new SVSCentralDataContext();
object levels;
if (_intParentLevelId == 0)
{
levels = (from sl in _svsCentralDataContext.SVSSurvey_Levels
where sl.ParentLevelID == null && sl.SurveyID == _intSurveyId
select new
{
sl.ID,
sl.SurveyID,
sl.UserCode,
sl.ExternalRef,
sl.Description,
sl.ParentLevelID,
sl.LevelSequence,
sl.Active
});
backUpButton.Visible = false;
}
else
{
levels = (from sl in _svsCentralDataContext.SVSSurvey_Levels
where sl.ParentLevelID == _intParentLevelId && sl.SurveyID == _intSurveyId
select new
{
sl.ID,
sl.SurveyID,
sl.UserCode,
sl.ExternalRef,
sl.Description,
sl.ParentLevelID,
sl.LevelSequence,
sl.Active
});
}
grdLevels.DataSource = levels;
grdLevels.DataBind();
GrdLevelButtons();
}
How can I convert this information to use my Treeview control?
This is my solution.
On my code behind page:
private void BuildTree()
{
tvLevels .Nodes.Clear();
_svsCentralDataContext = new SVSCentralDataContext();
List<DataAccessLayer.Level> items = DataAccessLayer.Levels.GetLevels(_intSurveyId).ToList();
List<DataAccessLayer.Level> rootItems = items.FindAll(p => p.ParentLevelId == null);
foreach (DataAccessLayer.Level item in rootItems)
{
var tvi = new TreeNode(item.Description, item.Id.ToString(CultureInfo.InvariantCulture) );
BuildChildNodes(tvi, items, item.Id);
tvLevels.Nodes.Add(tvi);
}
}
private void BuildChildNodes(TreeNode parentNode, List<DataAccessLayer.Level> items, int parentId)
{
List<DataAccessLayer.Level> children = items.FindAll(p => p.ParentLevelId == parentId).ToList();
foreach (DataAccessLayer.Level item in children)
{
var tvi = new TreeNode(item.Description, item.Id.ToString(CultureInfo.InvariantCulture));
parentNode.ChildNodes.Add(tvi);
BuildChildNodes(tvi, items, item.Id);
}
}
Class Levels.cs
using System;
using System.Collections.Generic;
using System.Linq;
using SVSVoidSurveyDesigner.Database;
namespace SVSVoidSurveyDesigner.DataAccessLayer
{
public class Levels
{
public static IEnumerable<Level> GetLevels(int intSurveyId)
{
var dataContext = new SVSCentralDataContext();
var levels = (from l in dataContext.SVSSurvey_Levels where l.SurveyID == intSurveyId
select new Level
{
Id = l.ID,
SurveyId = l.SurveyID,
UserCode = l.UserCode ,
ExternalRef = l.ExternalRef ,
Description = l.Description ,
ParentLevelId = (l.ParentLevelID),
LevelSequence = ( l.LevelSequence ),
Active = Convert .ToBoolean( l.Active )
});
return levels;
}
}
}
Class Level.cs
namespace SVSVoidSurveyDesigner.DataAccessLayer
{
public class Level
{
public int Id { get; set; }
public int SurveyId { get; set; }
public string UserCode { get; set; }
public string ExternalRef { get; set; }
public string Description { get; set; }
public int? ParentLevelId { get; set; }
public int? LevelSequence { get; set; }
public bool Active { get; set; }
}
}