WPF - Categorized ListView - c#

Data Types
My MainWindow has a property called Project project which has a property ObservableCollection<Drawable> Drawables
public class Drawable {
public enum DrawableType { Top, Head, Feet };
public bool IsMale {get; set;}
public bool IsFemale {get; set;}
public DrawableType DrawableType {get; set;}
public string DisplayName {get; set;}
}
For all Data types and properties I properly implemented the INotifyPropertyChanged interface.
Current situation
The ObservableCollection is displayed in a ListView but as it contains up to about 500 items it is hard to use the application. I would like to display the items in a TreeView-like structure categorized by the gender (IsMale, IsFemale) and the DrawableType like this:
Male
Top (Drawables are display here if IsMale=true and DrawableType=DrawableType.Top)
Drawable 1
Drawable 2
Drawable 3
Head
Feet
Female
Top (Drawables are display here if IsFemale=true and DrawableType=DrawableType.Top)
Drawable 2
Head
Feet
In this example Drawable 2 has IsFemale=true, the others have false.
My problem
During research I found that ListView actually supports grouping but I don't think this is what I want as a single instance of Drawable can be a children of up to two nodes (as with Drawable 2 belongs both to Male->Top and Female->Top)
What I have tried
I tried using a TreeView which provides all the visuals I need for this task but I can not get it to categorize the Drawable instances. I tried subscribing to the PropertyChanged and CollectionChanged events to create an ObservableCollection in order to create a structure that I can directly bind the TreeView to:
public class DrawableListEntry : INotifyPropertyChanged {
public enum Sex {Male, Female}
public Drawable Drawable;
public DrawableType DrawableType = DrawableType.None;
public Sex Sex = Sex.None;
public string Label {
get {
if(Drawable != null) { return Drawable.DisplayName; }
if(DrawableType != null) { return DrawableType.ToString(); }
return Sex.ToString();
}
}
public ObservableCollection<DrawableListEntry> Children {get; set;}
}
My Question
Is it possible to directly bind to the ObservableCollection and let a TreeView do the categorization automatically?
Please keep in mind, that I'm currently not adhering to any patterns like MVVM but I try to keep my business logic apart from the UI.

During research I found that ListView actually supports grouping but I don't think this is what I want as a single instance of Drawable can be a children of up to two nodes (as with Drawable 2 belongs both to Male->Top and Female->Top)
Create a DrawableViewModel class with Gender, DrawableType and DisplayName properties and then add an instance of this class for each leaf entry that you want to display in the grouped ListView.
In this particular example you will then end up with a source collection of four items; Drawable 1, Drawable 2, Drawable 3 and another Drawable 2 (with the Gender property set to Female unlike the first one).
In other words, you should use the MVVM design pattern to basically transform your data model into something that works with the ListView control in the view.

Related

Bind different kinds of objects containing lists of other objects to a TreeView

Hello im new to WPF and i created a datastructure and i want to show my different kind of objects in a TreeView and im a little confused where to begin and how.
This is what my datastructure looks like:
public class Product {
public int ID;
}
public class ProductType1 : Product {
public double Length;
public List<Profile> Profiles = new List<Profile>();
public List<Item> Items = new List<Item>();
}
There can be more Product Types, but they are very diffrent and just have a ID in common. And only one at the same time should be loadable in the TreeView.
public class Profile {
public String Name;
public List<Rectangles> Rectangles = new List<Rectangles>();
}
public class Rectangle {
public double K1;
public double K2;
}
public class Item {
public String Name;
public String Color;
}
Later the TreeView should look like this:
-ProductName
--Type: ProductType1
--ID: 1234
--Length: 5000
-Items
--Item1
--Item2
---Colour: blue
-Profiles
--Profile1
--Profile2
---Rectangle1
----K1: 55
----K2: 80
My Questions now are:
1.How do i realize the data binding when i want to display ProductType1. I read sth. about HierarchicalDataTemplates. What would the XAML looks like especially the and the TreeView Binding Part. Do i need extra ViewModels ?
2.How do i realize the data binding in combination with the different Product Types which have just the ID in common. Do i need different DataTemplates for each product and how do i select them.
I hope you can help me and provide me some helpful links!

Xceed WPF Propertygrid - Collection Control: Multiple Types

I'm using the Xceed WPF Property Grid control to edit properties of objects and collections of objects. I noticed that the collection editor has the option of selecting a type, as seen in the image below. How would I go about adding multiple types that inherits from a base class?
For example, I have a class Presentation which have a list of Slides. Multiple Slide types (classes) could exist that inherits from Slide (main Slide class). See code below. The idea is to link the Property Grid to the Presentation object (Presentation class), and when the Slides collection is edited, the Collection Editor will have all the slide types available which can be selected via the "Select Type" combo box.
This will enable the user to seamlessly add different slide types that is stored in one collection object (List).
Any idea how I can make this work?
public class Presentation
{
private List<Slide> _slides = new List<Slide>();
[DisplayName("Slides List")]
[Description("Slides List")]
[Category("Presentation Content")]
[PropertyOrder(1)]
public List<Slides> slides
{
get
{
return (_slides );
}
set
{
_slides = value;
}
}
public class Slide
{
//Properties of slide
}
public class SlideType1: Slide
{
//Properties of slide type 1
}
public class SlideType2: Slide
{
//Properties of slide type 2
}
}
Seems like I found the answer! Need to use the code below:
[NewItemTypes(typeof(Slide1), typeof(Slide2))]

How Do I Bind Two HTML Elements to the same object in ASP MVC 3?

This is a simple question, but I am new to MVC and ASP.NET, so more explanation is better on this one. I have a Portfolio class that has a list of industries associated with it. The classes (simplified) are below:
public class Portfolio
{
public int Id {get; set;}
public List<Industry> IndustryList {get; set;}
}
public class Industry
{
public int Id {get; set;}
public double value {get; set;}
public string Name {get; set;}
public int PortfolioId {get; set;}
}
Suppose I want to create a simple View that will allow a user to edit the properties of one portfolio.
On the view page, I want to create 2 text boxes and 2 drop down lists. Then the user would be able to select an industry from the drop down lists and then input some value in the associated text box. What I would want is the IndustryList for that Portfolio to contain the 2 Industry objects.
For instance:
DropDownList1 has "Fast Food" selected. The textbox associated to
that same object has a value of 2.5.
DropDownList2 has "Fashion"
selected. The textbox associated to that same object has a value of
45.3.
The list for that Portfolio would have two Industry objects with the data from the example.
Is it possible to map two or more HTML objects (i.e. textboxes, dropdowns, etc) in a View to a single object in a collection like this?

Performant editing and traversing of a hierachical list

I'm having trouble editing fields/properties in a hierarchical list with the help of a second lookup list. Everything I try looks like a mess and is hard to maintain. Are binary search trees my friend? How would I apply them? Flattening my hierarchical structure doesn't work as I need the hierarchy, just filtered.
public class Filter
{
public string Name {get;set;}
public bool IsActive {get;set;}
public bool IsDisplayed {get;set;}
public string List<Filter> Filters {get;set}
}
public List<string> ActiveFilters {"Green", "LighterYellow", "Red", "Meep")};
My base filters basically look like this:
Colors
Green
Yellow
LightYellow
LighterYellow
OrangishYellow
Red
DarkRed
Sounds
Meep
Moop
Maap
Now I'm trying to set some of these filters to active. But of course the parents of children who are in the ActiveFilters need to be displayed (IsDisplayed) otherwise you wouldn't be able to see the child items.
In the end I want the hierarchy to look like this (based on applying the ActiveFilters, bold indicates IsActive, italic IsDisplayed):
Colors
Green
Yellow
LightYellow
LighterYellow
Red
Sounds
Meep
I have been trying to recursively loop through the hierarchical list, but I don't know how to set the parents to IsDisplayed (as I would have to "go back up"). When looping the other way through the ActiveFilters I don't want to iterate over the whole filter list for each active filter performance wise.
I would do something like this:
First, add a Parent property to Filter
public class Filter
{
public string Name {get;set;}
public bool IsActive {get;set;}
public bool IsDisplayed {get;set;}
public string List<Filter> Filters {get;set}
// Parent
public Filter Parent {get;set;}
}
In your initialization code for the hierarchy, make sure you populate Parent correctly. (I don't know what your code looks like, so I'll leave that part to you.)
Next, in your code that highlights the active filters, do something like:
var parent = activeFilter.Parent;
while (parent != null)
{
parent.IsDisplayed = true;
parent = parent.Parent;
}

How to bind a TreeView Hierarchically by using enum values in WPF

Ok, so I am not sure this is even possible but I will ask the question here and hope to get an answer to it.
Suppose I have a list of a class, say Media items defined as follows
Enum MediaItemType{
Book,
CD,
VideoGame
}
public MediaItem{
public string Name { get; set; }
public MediaItemType { get; set; }
}
Now suppose I want to bind a list of MediaItems to a TreeView such that each MediaItem ends upp in a separate subtree depending on the media item type. Is that possible to do and if so, how do I do that?
In my Xaml-code I assume that I have defined the list as a property named MediaItems in the context.
<Grid>
<TreeView ItemsSource="{Binding Path=MediaItems}">
</Grid>
The tree view should be something like this
Book
- In to the wild
- Code Complete
CD
- Foo Fighters
- Bach
DVD
- X-men
- Casino Royale
Don't see any problem.
In model you have MediaItem, on model view you have to have MediaItemView type, something like this:
public class MediaItemView
{
public MediaItemType { get; set; }
public List<MediaItem> medialist;
}
Define bindings on that class, and define a Converter which will convert enum value to its string presentation.
I don't know about about a tree view, but you could achieve something similar to what you describe using a GroupDescription grouping on the MediaItemType property with a ListBox or ListView as described here

Categories