Update Single Item in the ObservableCollection without LINQ - c#

I am trying to create a list of the Components running on the network. I am trying to get all the components in the ObservableCollection. ObservableCollection<ClsComponent> Now my question is if one of the component in the collection get changed / modified how would I be able to get it reflected to my ObservableCollection of Component
Is there a way to change the it directly in the collection itself?
What is the fast and efficient way doing it?
I have tried: to change it using the LINQ : Find the Component in the collection and change it?
var CompFound = Components.FirstOrDefault(x=>x.Id == myId);
Components.Remove(CompFound);
Components.Add(UpdatedComp);
I am very sure there should have been more optimized way of doing this. Please suggest.
Edit
I am trying to write the code in the function where I can get the parameters of Source Component and Destination Component. Function looks like this
public void UpdateComponent(ClsComponent SourceComp, ClsComponent DestComp)
{
//do something here
}
After the execution of the function I want to Replace Source Component with Destination Component.

I believe this might work for you. I am sure you might be looking for this
Components.Insert(Components.IndexOf(SourceComp), DestComp);
Components.Remove(SourceComp);

One of the most efficient way would be to use a dictionary. There are implementations of ObservableDictionary which will give you the Observable behavior while allowing a fast key-based access to the object.
Check this stackoverflow question. It includes Microsoft's
It should work like ObservableCollection, except it's also a dictionary. So you can Create ObservableDictionary<Int,ClsComponent>
To replace the value simply call
Components[myId] = destComp

Related

Get selected items in solution with native interfaces

I am trying to get all selected items in a solution and this with native code. With native code I am referring to code which does not use the DTE.
I checked the documentation and tried to find a suitable solution, however I din't come very far. What I found was the IVsUiHierarchy which contains the ExecCommand method which contains the following.
Commands that act on a specific item within the hierarchy. (If ItemID equals VSITEMID_SELECTION, the command is applied to the selected item or items.)
So I suspect the method they are talking about, is the before mentioned ExecCommand one. For one I am not quite sure how I will get to the IVsHierarchy object from a IVsHierarchy or similar, on the other hand I am not really sure on how to use the ExecCommand method properly. Additionally I am not even quite certain, if this is even the 'right way' of approaching this.
Note: I am searching for a solution which does not contain the following code in this answer.
You can use IVsMonitorSelection.GetCurrentSelection, to identify all the selected items in the solution explorer.
The above will return you an IVsMultItemSelect interface which you can use to invoke IVsMultiItemSelect.GetSelectedItems to retrieve an array of VSITEMSELECTION values.
There are a few extensibilty samples, that utilize GetSelectedItems, you can use as a reference.
Sincerely,
Ed Dore

Proper way to refresh ObjectListView (TreeListView) after removing object from List

I'm using ObjectListView (http://objectlistview.sourceforge.net/) and trying to update/refresh GUI after removing an object in List. Simple code:
appropriateParent.Entity.Values.RemoveAll(x => x.Id == value.Id);
Now, what's the appropriate way to update the TreeListView?
treeListView.RebuildAll(false); or
treeListView.RefreshObject(parameterNodeParent);
returns "System.ArgumentOutOfRangeException"
Any Ideas?
Best regards,
According to the FAQ, the listView does not know when you make a change. Therefor you can do one of the following:
If you can simply reset the iEnumerable by calling listView.SetObjects(iEnumerable), wich will then update the listview.
If all you do is update part of the list you can call listview.UpdateObjects(iEnumerable). Note that this does not know when objects are removed!
If you know wich objects are removed you can remove them by calling listview.RemoveObjects(iEnumerable).

Run a method everytime a List is modified (not accessed)

This is very similar to the question but specific to Lists.
How to trigger event when a variable's value is changed?
Every time my list is modified I want to run a method.
I assumed using a property and putting a method within 'set' would be the correct way to approach this. I started with something like this
public class Stuff
{
private List<Things> _myThings;
public List<Things> MyThings
{
get
{
return _myThings;
}
private set
{
_myThings= value;
runWhenListIsChanged();
}
}
}
However, when I use a command like 'RemoveAt' or 'RemoveRange'
public class StuffChanger
{
Stuff.MyThings.RemoveAt(5);
}
It goes straight into the 'get' property and the list is changed.
I wrongfully presumed it would use set (as its changing the list) but that's not the case. When debugging (using the 'step into' tool in Visual Studio) I noticed the List can be modified by using the 'get' accessor.
In this particular case, I don't want to have a method being called every time the list is read by something, as this could get performance heavy or cause a stack overflow. So that isn't an option.
I'd be very grateful if anyone has any tips or code suggestions! Thanks very much.
As you have observed, the code you wrote to manipulate the list does in fact not set a new list into the property.
Instead, this code:
Stuff.MyThings.RemoveAt(5);
can be thought of as similar to this:
var list = Stuff.MyThings;
list.RemoveAt(5);
As such, it reads the list out of the getter, and then directly manipulates the list itself.
To get notifications when the list itself is changing, you will need to use something other than List<T> since this type does not have any functionality to support that requirement.
A good candidate would be ObservableCollection<T> and you would hook up an event handler to the CollectionChanged event.
Please note that this will only observe changes to the list, and not to the elements in the list. If you add or remove an item from the list, you will get notifications but if you execute code like this:
MyStuff.MyThings[0].SomeProperty = SomeNewValue;
then you will not get any notifications from the list itself. You will have to implement something like INotifyPropertyChanged on the element types, and hook up event handlers to that to get those notifications.

Copying from EntityCollection to EntityCollection impossible?

How would you do this (pseudo code): product1.Orders.AddRange(product2.Orders);
However, the function "AddRange" does not exist, so how would you copy all items in the EntityCollection "Orders" from product2 to product1?
Should be simple, but it is not...
The problem is deeper than you think.
Your foreach attempt fails, because when you call product1.Orders.Add, the entity gets removed from product2.Orders, thus rendering the existing enumerator invalid, which causes the exception you see.
So why does entity get removed from produc2? Well, seems quite simple: because Order can only belong to one product at a time. The Entity Framework takes care of data integrity by enforcing rules like this.
If I understand correctly, your aim here is to actually copy the orders from one product to another, am I correct?
If so, then you have to explicitly create a copy of each order inside your foreach loop, and then add that copy to product1.
For some reason that is rather obscure to me, there is no automated way to create a copy of an entity. Therefore, you pretty much have to manually copy all Order's properties, one by one. You can make the code look somewhat more neat by incorporating this logic into the Order class itself - create a method named Clone() that would copy all properties. Be sure, though, not to copy the "owner product reference" property, because your whole point is to give it another owner product, isn't it?
Anyway, do not hesitate to ask more questions if something is unclear. And good luck.
Fyodor
Based on the previous two answers, I came up with the following working solution:
public static void AddRange<T>(this EntityCollection<T> destinationEntityCollection,
EntityCollection<T> sourceEntityCollection) where T : class
{
var array = new T[sourceEntityCollection.Count()];
sourceEntityCollection.CopyTo(array,0);
foreach (var entity in array)
{
destinationEntityCollection.Add(entity);
}
}
Yes, the usual collection related functions are not there.
But,
1. Did you check CopyTo method?
2. Do you find any problem with using the iterator? You know, GetEnumerator, go through the collection and copy the entities?
The above two can solve your problems. But, I'm sure in .NET 3.0+ there would be compact solutions.
My answers are related to .NET 2.0

Using ASP.NET Repeaters with Object Properties

I'm trying to use ASP.NET's Repeater objects to loop over properties of an object.
For example... I have an ObjectDataSource to grab object "Program" by ID...
Program has properties such as Program.Stakeholders and Program.Outcomes which are Lists of "Stakeholder" and "Outcome" objects.
Now... what I'd really like to do is use the Repeaters to target these Properties and loop over the lists they contain. However, as far as I know I'd have to set up a separate data source for each one, tied to an individual method to retrieve each list.
Can anyone provide a better way to use these Repeater objects, or point me at some resources which would help? If this doesn't make sense I can try to clarify it more.
Using the built-in ObjectDataSource mapping up a separate datasource for each item is probably the only straightforward way (and the only way that's easy enough to be worth the effort...).
Is it a requirement that you use the ObjectDataSource, or can you choose a different way to get the data from the storage? I would recommend either using Entity Framework (which imho rocks) or creating your own custom types to which you get the data with a custom designed DAL (which is a lot more work than using EF, but if you're, like some, concerned that EF is still in infancy this might be your option).
In either case, you'll end up with a C# class called Program, which has properties of type IEnumerable<Stakeholder> and IEnumerable<Outcome> called Stakeholders and Outcomes respectively. You can then use these as datasources for the item repeaters and set them in the ItemDataBound event of the ProgramRepeater, maybe something like this:
protected void ProgramRepeater_ItemDataBound(object sender, ItemDataBoundEvent e) {
Program dataItem = (Program)e.DataItem;
Repeater stakeholderRptr = (Repeater)e.Item.FindControl("ProgramRepeater");
Repeater outecomeRptr = (Repeater)e.Item.FindControl("OutcomeRepeater");
stakeholderRptr.DataSource = dataItem.Stakeholders;
stakeholderRptr.DataBind();
outecomeRptr.DataSource = dataItem.Outcomes;
outecomeRptr.DataBind();
}
This is assuming that you're using ASP.Net WebForms, of course. In ASP.Net MVC it is even easier - you just send the Program object to the View as the Model object, and loop through its Stakeholders and Outcomes in a couple of nested for loops directly on the View.
Note: All code is provided as is, and I do not guarantee that it will run as expected or even compile. It is just to give you an idea of what to make your code do - not necessarily the exact code you need to solve your problem.

Categories

Resources