If I have been researching this correctly, I got some help before and a user said that it would be good to use a Dictionary to store my Country and Places.
So I create my Dictionary:
Dictionary<string, NewCountryClass> NTCD = new Dictionary<string, NewcountryClass>();
When the user clicks the button it will trigger this class where I wanted it to create a instance of newCountryClass inside the Dictionary at runtime. It would add the string which would be the newCountryTitle.Country and then the Class.
public void AddCountryCollection()
{
newCountryClass = new NewCountryClass(newCountry,"");
Collections.Add(newCountryClass);
NTCD.Add(newCountryClass.Country, newCountryClass);
}
So lets say the user has has added the Country which has created this Dictionary at Runtime, and they have added 4 Countries, but now want to go back and add a Place label inside the second Country.
This is the newCountryClass:
private string _country;
public string Country
{
get { return _country; }
set
{
if (_country.Equals(value))
return;
_country= value;
RaisePropertyChanged(() => Country);
}
}
private ICollection<string> _places;
public ICollection<string> Places
{
get
{
if (_places== null)
_places= new ObservableCollection<string>();
return _places;
}
set
{
if (value == _places)
return;
_places= value;
RaisePropertyChanged(() => Places);
}
}
If they have created 4, and they want to add a Place to the list inside that Country of the second one they created, how would I find it?
I found an answer I simply use the key I stored:
NTCD["GER"].Places.Add("New Place inside GER");
If I only want to know the second one, either take a List<NewCountryClass> and iterate by index with foror take a OrderedDictionary. It takes object key, object value as parameters on add and I can access it via NTCD[3].
Related
in my page1.aspx.cs I have this
resultsHtml.Append("<a class='btn btn-warning' href='report.aspx?asset=" + rd["n_asset_id"].ToString() + "'><i class='fa fa-paw'></i></a> ");
so in my report.aspx I will catch the value.
Session["passThis"] = Request.QueryString["asset"];
However in my action.cs I created a class that will store the list. I'm thinking of adding a session there but everytime i will the store() it will just create another List.
public static void store() {
List<string> ast = new List<string>();
}
How can I achieve this feat? I'm running out of ideas.
I think that the best approach would be to extract assets list into property (so you can easily access it from other parts of code. In property getter, code checks if there's list in session.
In Store method you're accessing List of assets (List<string) and, if there is asset parameter in current Request, adds it to your list of assets. Notice that accessing Session is done through HttpContext.Current.Session because of static metod/property.
public static void Store()
{
string assetValue = HttpContext.Current.Request["asset"];
if (!string.IsNullOrEmpty(assetValue))
AssestsList.Add(assetValue);
}
public static List<string> AssestsList
{
get
{
if (HttpContext.Current.Session["assets"] == null)
{
HttpContext.Current.Session["assets"] = new List<string>();
}
return HttpContext.Current.Session["assets"] as List<string>;
}
set
{
HttpContext.Current.Session["assets"] = value;
}
}
so, to use this, just call Store() from your code.
If you have some questions, feel free to ask.
I want to create a query with linq on my ObservableCollection but it doesn't really work how T tried it.
I have a Model Entry which has {note, information, isActive} as parameters. So I now want to simply just get all the Entries where isActive is true. I don't use it on my dataprovider (once the data gets loaded) because I need to load every entry into the program.
So I thought about to override the getter inside my entries ObservableCollection:
public ObservableCollection<Note> _entries { get; set; }
public ObservableCollection<Note> entries
{
get
{
return new ObservableCollection<Note>(from entry in this._entries
where entry.isActive == true
select entry);
}
set { this._entries = value; }
}
But as you might guess this doesn't work.
Regards
Try
get
{
List<Notes> list = _entries.Where(e=>e.isActive).ToList();
return new ObservableCollection<Note>(list) ;
}
Rather than editing it in the get, try updating the refinedEntries in the entries' setter. My Linq statement may need work but it encapsulates what I'm trying to suggest.
Essentially keep a copy of everything even the inactive records in entries and another collection to contain only the active records. In this case I'm calling it refinedEntries.
private ObservableCollection<Note> _entries;
public ObservableCollection<Note> entries
{
get{return _entries;}
set
{
_entries = value;
RefinedEntries = new ObservableCollection(_entries.Where(e=>e.isActive).Select(e => e));
}
}
public ObservableCollection<Note> refinedEntries {get;set;}
I would also suggest updating refinedEntries when CollectionChangedEvent fires. In this case the only time refinedEntries is updated is when entries is set to a new instance.
When you instantiate an new collection for entries, subscribe to its CollectionChangedEvent. For example if you instantiate the collection in the Model's constructor you could use the following..
entries = new ObservableCollection<Note>();
entries.CollectionChangedEvent += new NotifyCollectionChangedEventHandler((sender,args) =>
{
RefinedEntries = new ObservableCollection(_entries.Where(e=>e.isActive).Select(e => e));
//Notify the UI that an update has been made.
OnPropertyChanged("RefinedEntries");
});
I'm fairly new to WPF and I've been reading many tutorials and yet while I could find many guides that showed how to bind data to textboxes and such, I couldn't find anything about navigating such data through back/forward/etc. buttons.
This is my current situation: I have a Customer class containing data on a single customer and a Customers class which is an ObservableCollection of customer.
Then data is loaded from an sqlite database (and this opens another can of worms because I don't know the exact approach for working this out but it doesn't really pertain to the current issue since I more or less got it to work) and every customer is added to the collection.
Then in the ViewModel for the main form I have the following stuff:
private Customer _objCustomer;
private Customers _customers;
private Customer _selectedCustomer;
public Customer Selection { get { return _selectedCustomer; }
set
{
if (object.ReferenceEquals(value, _selectedPartecipante)) { return; }
_selectedCustomer = value;
base.OnPropertyChanged("Selection");
}
}
public Customers customers { get { return _partecipanti; }
set { _customers = value; base.OnPropertyChanged("customers"); } }
public Customer customer { get { return _objCustomer; }
set { _objCustomer = value; base.OnPropertyChanged("customer"); } }
public string Name { get { return _objCustomer.Name; } set { _objCustomer.Name = value; base.OnPropertyChanged("Name"); } }
public int Id { get { return _objCustomer.Id; } }
public SubscriptionsViewModel()
{
_customers = Customers.LoadCustomers(); //This one loads the items from the database
_objCustomers = _customers.First();
_selectedCustomer = _objCustomer;
}
This is probably wrong but I still can't find a way to fix it, what am I supposed to work to get navigation working?
And how do I get the data in the current record to be saved when pressing a certain button on the form?
Try to put the exact property in OnPropertyChanged("Customers");
In your case, the property is lower case.
I have created a simple C# Windows 8 grid application.
If you're unfamiliar with this layout, there is a brief explanation of it here :
Link
What I would like to have is simple - some custom ItemDetailPages. I'd like to be able to click on some items on the GroupDetailPage and the GroupedItemsPage and navigate to a custom .xaml file, one where I can include more than one image.
I'm sure there is a simple way of doing that that I have missed out on, and I'm also sure that this information will be useful for a lot of people, so I will be offering a bounty on this question.
I have struggled with doing this so far :
I've created a CustomDataItem in the SampleDataSource.cs class :
/// <summary>
/// Generic item data model.
/// </summary>
public class CustomDataItem : SampleDataCommon
{
public CustomDataItem(String uniqueId, String title, String subtitle, String imagePath, String description, String content, SampleDataGroup group)
: base(uniqueId, title, subtitle, imagePath, description)
{
this._content = content;
this._group = group;
}
private string _content = string.Empty;
public string Content
{
get { return this._content; }
set { this.SetProperty(ref this._content, value); }
}
private SampleDataGroup _group;
public SampleDataGroup Group
{
get { return this._group; }
set { this.SetProperty(ref this._group, value); }
}
}
However, obviously, adding to the ObservableCollection
private ObservableCollection<SampleDataGroup> _allGroups = new ObservableCollection<SampleDataGroup>();
public ObservableCollection<SampleDataGroup> AllGroups
{
get { return this._allGroups; }
}
is impossible with a different data type. So what can I do in this case ?
Thanks a lot.
I have a simple grid application; how do I make it possible to have one of the elements in the group item page link to a custom item detail page ?
Ok, lets take the app that is generated when using the "Grid App" template from Visual Studio.
The data class for the elements on the group items page is the SampleDataItem class. What you can do is add some type of data field (bool, int, or other) that indicates how to handle the navigation. In this example, we are keeping it simple, so we add a bool to indicate whether the navigation is custom or not.
public class SampleDataItem : SampleDataCommon
{
// add flag as last param
public SampleDataItem(String uniqueId, String title, String subtitle,
String imagePath, String description, String content, SampleDataGroup group,
bool isCustomNav = false)
: base(uniqueId, title, subtitle, imagePath, description)
{
this._content = content;
this._group = group;
this.IsCustomNav = isCustomNav;
}
// to keep it simple this doesn't handle INotifyPropertyChange,
// as does the rest of the properties in this class.
public bool IsCustomNav { get; set; }
...
}
So when you are adding a new SampleDataItem object to be displayed, you just need to set the isCustomNav field in the constructor.
Now all we have to do is change the already existing click event handler in the grid on the grouped item page (GroupedItemsPage.xaml.cs):
void ItemView_ItemClick(object sender, ItemClickEventArgs e)
{
// Navigate to the appropriate destination page, configuring the new page
// by passing required information as a navigation parameter
var item = (SampleDataItem)e.ClickedItem;
var itemId = item.UniqueId;
if (item.IsCustomNav == false)
{
// default
this.Frame.Navigate(typeof(ItemDetailPage), itemId);
}
else
{
// custom page
this.Frame.Navigate(typeof(ItemDetailPage2), itemId);
}
}
All we are doing above is getting the selected item and then testing the navigation flag that we added earlier. Based on this we navigate to either the original ItemDetailPage or a new one called ItemDetailPage2. As I mentioned before, the navigation flag doesn't have to be a bool. It can be an int or enum or some other type that tells us where to navigate.
Note that if you want similar behavior on the GroupDetailsPage, you just have to update the click event handler there the same way.
Hope that helps.
Yes you should be able to create a custom or different data type. If you create a Win8 app using the grid template, you see that the template does three things for you:
1) It creates three types, SampleDataCommon, which is the base, SampleDataItem, which implements SampleDataCommon and adds two new properties - content and group, and SampleDataGroup which also implements SampleDataCommon, adds a method, ItemsCollectionChanged, and adds two properties, Items and TopItems.
2) It creates a class called SampleDataSource, in which a collection of SampleDataGroup is created and named AllGroups: ObservableCollection AllGroups.
3) It binds Items and AllGroups of SampleDataSource to objects in XMAL pages.
In your case, you use the same data structure. In other words, you will create a group with items, etc.
I now have two list box, lstStock and lstSupply. lstSupply consists of
-Pen
-Pencil
-Staple
-Stapler
-Folder
-Notebook
-Eraser
-Marker
and i have two button, one button named btnAdd and another btnRemove.
when i click on btnAdd i want the selected item in lstSupply to be added into lstStock which i have done by
lstStock.Item.Add(lstSupply.SelectedItem);
if i select the same item in lstSupply twice, I want it to be consolidated in lstStock.
for instance, if i select Pen twice, the list box shall give me "Pen x 2" instead of Pen in a line and another Pen in another line.
I got the feeling this is dealing with foreach but i dont really know how to use that.
Okay, so first of all, you're going to need to store something else in lstStock. I'd suggest something like this:
public class StockItem {
public string Name { get; set; }
public int Count { get; set; }
}
Next, I'd suggest that you don't use the .Items field as the actual container where you're storing your stock items. Instead, I'd have a List<StockItem> that you use to populate lstSupply when you refresh.
private List<StockItem> _items = new List<StockItem>();
Then, when you click "add", you do two things:
Iterate through _items to see if there is already a stock item in there of the matching supply. Create one, and add it, if it does not exist.
Find the matching stock item in _items and increment its Count.
To get it to display the way you'd like, we can override ToString() in our StockItem class.:
public class StockItem {
public string Name { get; set; }
public int Count { get; set; }
public override string ToString() {
if (Count > 1)
return Name + " x" + Count;
return Name;
}
}
Finally, whenever any changes are made, you simply re-populate lstStock:
private void RefreshGui() {
lstStock.Items.Clear();
lstStock.Items.AddRange(_items.ToArray());
}
There are plenty of other ways of going about this, but for this simple exercise, this is how I think I would do it.
If you want the code to work without extra coding, you could simply do this:
if (lstSupply.SelectedIndex > -1 && !lstStock.Items.Contains(lstSupply.SelectedItem))
lstStock.Items.Add(lstSupply.SelectedItem);
this way you are sure that you don't add null items and add each item once max.