How to create a binded copy of an object in c#? - c#

I have an object of class Employee (let us call it Alice), and want to create a copy of this object (let us call it Alice_again) such that if I change Alice, the properties of Alice_again also changes. Basically creating a copy of an object whose properties are bound to the original.
Edits
I am having two diferent ObservableCollection of Employee(Employee is User Control) and both contains same object Employee and I want to display each ObservableCollection once. For that I am using ItemsControl and I have binded ItemsSource of ItemsControl to these ObservableCollection and as I have read on this link that a given object may only be present in a given logical tree once, so I am trying to create a copy of object but I don't want to update both copies whenever there is an update.

You do not need to create a copy.
Since the elements in the ItemsSource collection are not supposed to be Visuals, two or more source collections may contain references to the same objects.
Two different UI elements in the ItemTemplate of two ItemsControl would hence legitimately bind to the same data item object.

object may only be present in a given logical tree once
logical tree is a tree of UI elements. Elements of a different type are not included in this tree.
For each item in the source collection, its own ContentPresenter will be created, which will be included in the logical tree of the parent ItemsControl.
And each ItemsControl creates its own collection from the ContentPresenter.
Therefore, different ContentPresenters will be created in different ItemsControls for the same source item and this will not create any problems.
You can even include the same item multiple times in the same collection.
And for each position of this element, its own ContentPresenter will be created.
dataTemplate has buttons whose content is binded to properties of Employee
A data template is, in fact, a factory for creating UI elements.
And when applying the template for each element, its own unique UI elements will be created.

Related

Two Controls Bound To Same Property WPF

I've got a ListBox and a DataGrid where the ListBox shows a subset of the list of the DataGrid. I created the two lists that the control's are bound to separately, however both control's SelectedItem are bound to the same property in the view model. I need to have both controls select the same item when the user clicks on either control's items unless the user clicks on the DataGrid on an item that is not in the ListBox's subset (then the ListBox should not have anything selected).
I'm guessing since the lists were created separately they are not the same object so is there a way to provide some sort of comparison logic to the controls to select an item that essentially has the same name (or value or some sort of criteria)? If that doesn't exist then I guess the best way would be to create the subset list of objects from the exact same objects in the superset.
I'm guessing since the lists were created separately they are not the same object
You could add the very same object to two different collections, e.g.:
YourType obj = new YourType();
list1.Add(obj);
list2.Add(obj);
This should solve your issue.
You could also override the Equals method of YourType as suggested in the comments but you shouldn't have to if both collections references the same objects, which they should since the second is a subset of the first.

Implement WPF TreeView of the same structure as another TreeView

I have a TreeView which data source is generated in runtime through code to which I don't have access. Its hierarchical data, nodes of tree with 2, 3 or 4 depth levels. I have to make the same structured tree with RadioButtons corresponding to every object in first tree. Is there a way to iterate through every element of TreeView or another method to do my task?
In WPF, we use DataTemplates, or in your case HierarchicalDataTemplates to define how our data should be presented. You already have the data in the first TreeView and that should be accessible from its ItemsSource or Items properties. Therefore, all you need to do is to define another HierarchicalDataTemplate to display the same data object the way that you want it. There is no need to manually iterate through all of the nodes from the original TreeView.

Binding to a user-defined list

I have a MultipleImageEntryHost (a self-defined child of WindowsFormHost), which contains a list (specifically an ObservableCollection) of FileInfos. I want to bind this list - that is, make sure that the source of the data (a MultipleImageEntry's list of FileInfos) will update the list. While obviously I want the public to have access to this list (the binding needs it), I don't want them to be able to switch the list object themselves. How do I do this?

Customizing the FrameworkElements used to display the contents of an ObservableCollection

So it seems like what I want to do should be straightforward, but I haven't been able to find a way to do it...
I need to display a list of objects that represent custom elements for entering data. Exactly how each object is displayed depends on the parameters of the object - so it could be a grid containing a name, description, and text box. It could be a grid with a couple labels and a dropdown. It could be an expander that contains multiple sub-objects. It could be something new that hasn't been built yet (so it needs to be extensible). Right now, I am populating this list by creating the FrameworkElement for each object and then adding it to a Grid by hand.
I would like to switch to keeping my objects in an ObservableCollection, and then binding that collection to a ListBox (or similar). That way, when new objects are added or removed from the list, the UI would automatically update itself accordingly. What I can't figure out is, is there a way to point it to my C# method for creating the custom-configured FrameworkElement for each object, so that when new objects are added the appropriate elements will be added to the UI?
Well, you're on the right track as far as wanting to use an ObservableCollection<T> and a ListBox control. Though, I'd venture to say you might want to simply use an ItemsControl since you probably don't care about selecting a particular item, but merely displaying an enumeration of items, and the ListBox would allow you to actually select one of those items.
Your problem is that you want each item in the list to display differently depending on certain criteria. For this you'll want to look at the DataTemplate and DataTemplateSelector classes.
Basically, a DataTemplate is a way of saying "I want my item to look like this.", and a DataTemplateSelector is a way of saying "I want to select this specific DataTemplate based on this criteria."
Here are a few examples on how to use the DataTemplate/DataTemplateSelector classes:
http://tech.pro/tutorial/807/wpf-tutorial-how-to-use-a-datatemplateselector
http://mikestedman.blogspot.com/2009/04/datatemplateselector.html
http://wpftutorial.net/DataTemplates.html
Seperating the presentation from the model is always a good idea. It seems like you are on the right track.
Foreach object type, you should create a DataTemplate and then use ItemTemplateSelector to select the correct template for each object type.
Good luck

How can I manually add an item to GridView.Items after binding ItemsSource?

I currently have a GridView populated with ItemsSource binding to an ObservableCollection.
It's showing the items as I intended but I'd like to manually add one more item at the end that looks and behaves differently. Is there a way I can do it without modifying the ObservableCollection the ItemsSource is bound to?
There are two approaches to this:
Using MVVM the original collection would be pulled up from the model layer and the additional item would be added in the view-model. It works as you can consider the additional item required only for the view, e.g. for example a list of poll options where you need to add an 'all of the above'.
Have two collections, separate, and then concatenate/join them together using an IValueConverter when you bind the ItemsSource. This approach is more tricky and only really useful when you need both collections separate and combined, e.g. a list of items in one collection and a list of item categories in another but also combined.
I have successfully used both approaches in a large widely-used WPF application.
Edit: Reading the comment on the question, if you did mean that you want a different visual or behaviour of the additional item you can achieve that using an Selector DataTemplateSelector and/or ItemContainerStyleSelector. I recently used a combination of option #2 and template selecting successfully.
Some options:
Use a CompositeCollection, you can define this is xaml. Not sure if it would solve the issue, you might need to play around with it a bit
Create a new collection behind the scenes that is populated with the items from your collection + the extra item.
Write a converter than creates a new collection (or returns an IEnumerable) with the new item added.
I guess all of these options have a common theme in that they are all a new collection. You basically can't bind directly to the original collection because it doesn't have the extra item, so you have to bind to something else in some form.

Categories