Is it possible to convert IEnumerable to a Custom Class that is inherting from ObservableCollection class?
Reason is I want to select only a filtered set of items on the get. I want to implement it on the get because lots of other properties reference CustomItems and perform processes on the items, but I want to somehow make it process filtered set of items depending if a value is enabled or not.
Below is code to help explain what I want to achieve:
public class CustomItemsCollection : ObservableCollection<ItemViewModel>
{
public ListView ListView { get; set; }
public void ScrollToItem(object item = null)
{
//Some custom Code
}
}
And here is my property that I want to customize:
private CustomItemsCollection _CustomItems = null;
[JsonProperty]
public CustomItemsCollection CustomItems
{
get
{
if (_CustomItems != null)
{
if(SomeValueIsEnabled)
{
var filteredItems = _CustomItems.Where(c => c.Property.equals(SomeValue));
var castedItems = (CustomItemsCollection)filteredItems;
return castedItems;
}
return _CustomItems;
}
_CustomItems = new CustomItemsCollection();
_CustomItemsChangedSource = new CollectionChangedWeakEventSource();
_CustomItemsChangedSource.SetEventSource(_CustomItems);
_CustomItemsChangedSource.CollectionChanged += _CustomItemsChangedSource_CollectionChanged;
return _CustomItems;
}
set { _CustomItems = value; RaisePropertyChanged("CustomItems"); }
}
Specifically, this part:
if(SomeValueIsEnabled)
{
var filteredItems = _CustomItems.Where(c => c.Property.equals(SomeValue));
var castedItems = (CustomItemsCollection)filteredItems;
return castedItems;
}
Is this possible / or maybe wrong? What is the best practice to do it?
Thank you!
You can't just cast it, but you can create an instance of CustomItemsCollection and initialize it with filteredItems.
Add a constructor to your custom class that passes through to the appropriate ObservableCollection constructor:
public class CustomItemsCollection : ObservableCollection<ItemViewModel>
{
public CustomItemsCollection(IEnumerable<ItemViewModel> items)
: base(items) { }
// your other code here
}
Then you can do this:
var filteredItems = _CustomItems.Where(c => c.Property.equals(SomeValue));
var collection = new CustomItemsCollection(filteredItems);
return collection;
Try with this code:
var filteredItems = _CustomItems.Where(c => c.Property.equals(SomeValue))
.Select(pre=> new ItemViewModel(){
//add info here
});
var castedItems = new CustomItemsCollection(filteredItems);
Related
On my viewModel I developed this code that will allow me to implement a research filter:
public ICollection<Nc> Ncs
{
get
{
var ncs = _ncManager.Ncs;
_ncCollectionView = CollectionViewSource.GetDefaultView(ncs);
_ncCollectionView.Filter = _DoesNcMatchFileNameFilter;
return ncs;
}
}
private ICollectionView _ncCollectionView;
This method works, but if I try to implement another similar method in another viewModel:
private ObservableCollection<Material> _materials;
public ObservableCollection<Material> materials
{
get
{
var materials = Material.Name;
_materialCollectionView = (CollectionViewSource)CollectionViewSource.GetDefaultView(materials);
_materialCollectionView.Filter = _DoesMaterialMatchFileNameFilter;
return Materials;
}
}
private CollectionViewSource _materialCollectionView;
I get an error: CollectionViewSrouce.Filter can only appear on the left hand side of += or -=".
Why can't I do the same thing? What did I do wrong?
I've tried to read this page ObservableCollection<> vs. List<> but it didn't help me.
should _materialCollectionView not be of type ICollectionView?
So:
private ObservableCollection<Material> _materials;
public ObservableCollection<Material> materials
{
get
{
var materials = Material.Name;
_materialCollectionView = CollectionViewSource.GetDefaultView(materials);
_materialCollectionView.Filter = _DoesMaterialMatchFileNameFilter;
return Materials;
}
}
private ICollectionView _materialCollectionView;
I have a ComboBox being populated where each object in ComboBox.Items is a List of objects. Currently the ComboBox displays "(Collection)" for each Item.
Is it possible to have the ComboBox display a member of the first object in the List that comprises an Item of the ComboBox?
I am currently populating the ComboBox items by the following:
foreach(List<SorterIdentifier> sorterGroup in m_AvailableSorterGroups)
{
// There are conditions that may result in the sorterGroup not being added
comboBoxSorterSelect.Items.Add(sorterGroup);
}
//comboBoxSorterSelect.DataSource = m_AvailableSorterGroups; // Not desired due to the comment above.
//comboBoxSorterSelect.DisplayMember = "Count"; //Displays the Count of each list.
The value that I would like to have displayed in the ComboBox can be referenced with:
((List<SorterIdentifier>)comboBoxSorterSelect.Items[0])[0].ToString();
((List<SorterIdentifier>)comboBoxSorterSelect.Items[0])[0].DisplayName; // public member
You can create an object wrapper and override the ToString() method:
public class ComboBoxSorterIdentifierItem
{
public List<SorterIdentifier> Items { get; }
public override string ToString()
{
if ( Items == null || Items.Count == 0) return "";
return Items[0].ToString();
}
public BookItem(List<SorterIdentifier> items)
{
Items = items;
}
}
You should override the SorterIdentifier.ToString() too to return what you want like DisplayName.
Now you can add items in the combobox like this:
foreach(var sorterGroup in m_AvailableSorterGroups)
{
item = new ComboBoxSorterIdentifierItem(sorterGroup);
comboBoxSorterSelect.Items.Add(item);
}
And to use the selected item for example, you can write:
... ((ComboBoxSorterIdentifierItem)comboBoxSorterSelect.SelectedItem).Item ...
I could imagine a few ways to do this... you could create a class that extends List<T>, so you have an opportunity to define the value you'd like to display.
public class SortedIdentifier
{
public string Name { get; set; }
}
public class SortedIdentifiers : List<SortedIdentifier>
{
public string SortedIdentifierDisplayValue
{
get { return this.FirstOrDefault()?.Name ?? "No Items"; }
}
}
Then use the new class like this:
comboBox1.DisplayMember = "SortedIdentifierDisplayValue";
var list = new SortedIdentifiers { new SortedIdentifier { Name = "John" } };
comboBox1.Items.Add(list);
I Follow MVVM model for my application, I have a textbox which acts as an input to filter the collection. I understood observablecollection filter using lambda expression but i couldn't understand collectionviewsource methods. how can i implement collectionviewsource methods using this.
Here is my viewmodel class:
private ObservableCollection<SPFetchCREntity> _CRmappings2 = new ObservableCollection<SPFetchCREntity>();
public ObservableCollection<SPFetchCREntity> CRmappings2
{
get { return _CRmappings2; }
set
{
_CRmappings2 = value;
RaisePropertyChanged("CRmappings2");
}
}
public ICollectionView AllCRSP
{ get; private set;}
public void UpdatePopList()
{
CRmappings2 = new ObservableCollection<SPFetchCREntity>(crentities.Where(p => p.MU_Identifier == selectmu.ToString()).ToList());
}
Bind to the ICollectionView and filter this one:
public void UpdatePopList()
{
CRmappings2 = new ObservableCollection<SPFetchCREntity>(crentities.ToList());
AllCRSP = CollectionViewSource.GetDefaultView(CRmappings2);
AllCRSP.Filter = obj =>
{
SPFetchCREntity entity = obj as SPFetchCREntity;
return entity != null && entity.MU_Identifier == selectmu.ToString();
};
}
private string _selectmu;
public string Selectmu
{
get { return _selectmu; }
set { _selectmu = value; AllCRSP.Refresh(); } //<-- refresh the ICollectionView whenever the selectmu property gets set or when you want to refresh the filter
}
I don't know how to add parameters to a list from a subclass. I have this class:
public partial class remSolicitudesEnt
{
private Solicitud[] solicitudesField;
public Solicitud[] Solicitudes {
get {
return this.solicitudesField;
}
set {
this.solicitudesField = value;
}
}
}
And in my code I have this:
private static remSolicitudesEnt getRemSolicitudesEnt()
{
remSolicitudesEnt filter= new remSolicitudesEnt();
//WHEN I ADD AN ELEMENT TO A NORMAL LIST...
List<Profesional> profesionals = new List<Profesional>();
Profesional p1 = new Profesional();
profesionals.Add(pd1);
//BUT HOW CAN I ADD AN ELEMENT TO A LIST FROM THE SUBCLASS??
Solicitud s = new Solicitud();
//filter.Solicitudes.Add(s); THIS CAN'T BE DONE
}
How Can I add the element "Solicitud" to the list?
Thanks in advance!
Your class is array not a list. So you have not method Add there. Just change definition of your
class:
public partial class remSolicitudesEnt {
private List<Solicitud> solicitudesField;
public List<Solicitud> Solicitudes
{
get { return this.solicitudesField; }
set { this.solicitudesField = value; }
}
}
How to add one object to ObservableCollection list object? I have class called "Assest" and I have created ObservableCollection list of Asset and I want to maintain it like adding and deleting element from that ObservableCollection list. Now I'm getting error when I try to add single element to ObservableCollection.
Here's my code.
private static ObservableCollection<Assest> _collection = null;
public ObservableCollection<Assest> AssestList
{
get
{
if (_collection == null)
{
_collection = new ObservableCollection<Assest>();
}
return _collection;
}
set { _collection = value; }
}
public static ObservableCollection<Assest> ToObservableCollection(List<Assest> assestList)
{
return new ObservableCollection<Assest>(assestList);
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
LoadData();
comboBox1.ItemsSource = AssestList;
}
private void LoadData()
{
Assest assest = new Assest() { AppID = "1", AssestName = "AppName", AppDescription = "Description" };
Assest assest2 = new Assest { AppDescription = "Des2", AppID = "2", AssestName = "hi" };
List<Assest> assList = new List<Assest> {assest, assest2};
ObservableCollection<Assest> generatedAssestList = ToObservableCollection(assList);
AssestList = generatedAssestList;
}
// Here I get an error.
public static void AddAppToObservalCollection(Assest ass)
{
_collection.Add(ass);
}
So How to over come these kind of situations. Thanks everyone.
Your code is a bit messy, it's not clear why you need both AssestList and _collection.
However, I think you need to replace
_collection.Add(ass);
with
AssestList.Add(ass);
_collection object still null while you call the getter of AssestList. So, when you use "_collection.Add(ass);", it can be null (and, btw _collection is private, so you can't access it from static function)
To avoid this, use always AssestList.