I had one list named category. It contains the following data.
Name - Id
----------------------------
Mobile - 0
Cellphones - 21
Mobile Accessories - 22
Camera - 0
Camcorder - 55
Camera Accessories 60
SLRs 61
Photo Printers 63
Computers 0
Laptops 65
Memory Cards 67
Monitors 69
RAM 70
Computer Accessories 71
And i want to display above data as following way using Ul and Li tag :
Mobile
-Cellphones
-Mobile Accessories
Camera
-Camcorder
-Camera Accessories
-SLRs
-Photo Printers
Computers
-Laptops
-Memory Cards
-Monitors
-RAM
-Computer Accessories
That is id=0 means parent category and id=non-zero means subcategory
Help me.Thanks in advance.
Namespace Test
Public Class Class1
Dim Categories As List(Of Category) = New List(Of Category) _
From {New Category With {
.ID = 0, .Name = "Mobile",
.Items = New List(Of CategoryItem) _
From {New CategoryItem With {.ID = 1, .Name = "Cellphones"},
New CategoryItem With {.ID = 2, .Name = "Mobile Accessories"}
}
},
New Category With {
.ID = 1, .Name = "Camera",
.Items = New List(Of CategoryItem) _
From {New CategoryItem With {.ID = 1, .Name = "Camcorder"},
New CategoryItem With {.ID = 2, .Name = "Camera Accessories"},
New CategoryItem With {.ID = 3, .Name = "SLRs"},
New CategoryItem With {.ID = 4, .Name = "Photo Printers"}
}
},
New Category With {
.ID = 2, .Name = "Computers",
.Items = New List(Of CategoryItem) _
From {New CategoryItem With {.ID = 1, .Name = "Laptops"},
New CategoryItem With {.ID = 2, .Name = "Memory Cards"},
New CategoryItem With {.ID = 3, .Name = "Monitors"},
New CategoryItem With {.ID = 4, .Name = "RAM"},
New CategoryItem With {.ID = 5, .Name = "Computer Accessories"}
}
}
}
Public Sub New()
Dim ul As String = SetCategories()
End Sub
Private Function SetCategories() As String
Dim ulCategories As XElement = <ul class="float-left"></ul>
For Each cat As Category In Categories
Dim currentCategory As Category = cat
Dim liCategory As XElement = <li><%= currentCategory.Name %></li>
Dim ulCategoryItems As XElement = <ul></ul>
For Each item As CategoryItem In currentCategory.Items
Dim currentItem As CategoryItem = item
Dim liItem As XElement = <li><%= currentItem.Name %></li>
ulCategoryItems.Add(liItem)
Next item
liCategory.Add(ulCategoryItems)
ulCategories.Add(liCategory)
Next cat
Return ulCategories.ToString()
End Function
End Class
Public Class Category
Public Property ID As Integer
Public Property Name As String
Public Property Items As List(Of CategoryItem)
End Class
Public Class CategoryItem
Public Property ID As Integer
Public Property Name As String
End Class
End Namespace
Here, put this in your view:
<ul>
<li>Mobile
<ul>
<li>Cellphones</li>
<li>Mobile Accessories</li>
</ul>
</li>
<li>Camera
<ul>
<li>Camcorder</li>
<li>Camera Accessories</li>
<li>SLRs</li>
<li>Photo Printers</li>
</ul>
</li>
<li>Computers
<ul>
<li>Laptops</li>
<li>Memory Cards</li>
<li>Monitors</li>
<li>RAM</li>
<li>Computer Accessories</li>
</ul>
</li>
</ul>
While that is what you are asking for, I think you are wanting something a little more.
Because there is nothing specific in your question or any attempt in your part, several assumptions where made in the following solution.
Class:
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public List<Category> Subcateogries { get; set; }
public Category()
{
Subcateogries = new List<Category>();
}
}
Controller:
public ActionResult Index()
{
//The Data
var categories = new List<Category>
{
new Category { Id = 0, Name = "Mobile" },
new Category { Id = 21, Name = "Cellphones" },
new Category { Id = 22, Name = "Mobile Accessories" },
new Category { Id = 0, Name = "Camera" },
new Category { Id = 55, Name = "Camcorder" },
new Category { Id = 60, Name = "Camera Accessories" },
new Category { Id = 61, Name = "SLRs" },
new Category { Id = 63, Name = "Photo Printers" },
new Category { Id = 0, Name = "Computers" },
new Category { Id = 65, Name = "Laptops" },
new Category { Id = 67, Name = "Memory Cards" },
new Category { Id = 69, Name = "Monitors" },
new Category { Id = 70, Name = "RAM" },
new Category { Id = 71, Name = "Computer Accessories" }
};
var GroupedData = new List<Category>();
foreach(var category in categories)
{
if(category.Id == 0)
{
GroupedData.Add(category);
}
else
{
GroupedData.Last().Subcateogries.Add(category);
}
}
return View(GroupedData);
}
View:
#model List<Category>
<h2>Categories</h2>
<ul>
#foreach (var topCategory in Model)
{
<li>#topCategory.Name
<ul>
#foreach (var subCategory in topCategory.Subcateogries)
{
<li>#subCategory.Name</li>
}
</ul>
</li>
}
</ul>
This is made with the assumptions that the starting list, in this case categories is in the order that you want. I also took a short cut by just reusing the original list items when I created the GroupedData. It is also assumed that there will only ever be two levels.
The view can be refactored to take advantage of partial views and handle multiple levels but that was not part of the question.
Related
Model
public partial class Official
{
public short OfficialNo { get; set; }
public string Surname { get; set; }
public string Firstname { get; set; }
}
I have 2 partial answers but neither gives me what I want:
In my controller on Edit:
ViewBag.OfficialNo = new SelectList(_context.Official, "OfficialNo", "OfficialNo", "", "Surname");
This gives me
Smith
111
Brown
102
Gray
103
The top line is bold and comes from "Surname" which is supposed to be the Data Group Field. The bottom line is what is stored in the database and displays a value if there is one (which is correct).
Alternatively
ViewBag.OfficialNo = new SelectList(_context.Official.Select(e => e.OfficialNo + " - " + e.Firstname + " " + e.Surname));
This gives me
101 – John Smith
102 – Bob Brown
103 – Garry Gray
which is the info I want but does not allow a selection to be stored (naturally).
I want
John Smith
111
Bob Brown
102
Garry Gray
103
so that the first line is info and the second line (if selected) will be what is stored on update.
How do I combine the 2 ViewBag statements above ?
For further info my Edit View statement is:
<div class="form-group">
<label asp-for="RefereeNo" class="control-label"></label>
<select asp-for="RefereeNo" class="form-control" asp-items="ViewBag.OfficialNo"><option> </option></select>
</div>
One of the solution is to add Group property of SelectListItem :
Controller :
var officials = _context.Official.GroupBy(x => x.Firstname+" "+x.Surname);
List<SelectListItem> selectListItems = new List<SelectListItem>();
foreach (var official in officials)
{
var optionGroup = new SelectListGroup() { Name = official.Key };
foreach (var item in official)
{
selectListItems.Add(new SelectListItem() { Value = item.OfficialNo.ToString(), Text = item.OfficialNo.ToString(), Group = optionGroup });
}
}
ViewBag.OfficialNo = selectListItems;
Then in view show/bind the dropdownlist :
<div class="form-group">
<label asp-for="#item.RefereeNo" class="control-label"></label>
<select asp-for="#item.RefereeNo" class="form-control" asp-items="ViewBag.OfficialNo"><option> </option></select>
</div>
As per Nan Yu's answer above:
Controller :
var officials = _context.Official.GroupBy(x => x.Firstname+" "+x.Surname);
List<SelectListItem> selectListItems = new List<SelectListItem>();
foreach (var official in officials)
{
var optionGroup = new SelectListGroup() { Name = official.Key };
foreach (var item in official)
{
selectListItems.Add(new SelectListItem() { Value = item.OfficialNo.ToString(), Text = item.OfficialNo.ToString(), Group = optionGroup });
}
}
ViewBag.OfficialNo = selectListItems;
I have a collection of items that contain an Enum (TypeCode) and a User object, and I need to flatten it out to show in a grid. It's hard to explain, so let me show a quick example.
Collection has items like so:
TypeCode | User
---------------
1 | Don Smith
1 | Mike Jones
1 | James Ray
2 | Tom Rizzo
2 | Alex Homes
3 | Andy Bates
I need the output to be:
1 | 2 | 3
Don Smith | Tom Rizzo | Andy Bates
Mike Jones | Alex Homes |
James Ray | |
I've tried doing this using foreach, but I can't do it that way because I'd be inserting new items to the collection in the foreach, causing an error.
Can this be done in Linq in a cleaner fashion?
I'm not saying it is a great way to pivot - but it is a pivot...
// sample data
var data = new[] {
new { Foo = 1, Bar = "Don Smith"},
new { Foo = 1, Bar = "Mike Jones"},
new { Foo = 1, Bar = "James Ray"},
new { Foo = 2, Bar = "Tom Rizzo"},
new { Foo = 2, Bar = "Alex Homes"},
new { Foo = 3, Bar = "Andy Bates"},
};
// group into columns, and select the rows per column
var grps = from d in data
group d by d.Foo
into grp
select new {
Foo = grp.Key,
Bars = grp.Select(d2 => d2.Bar).ToArray()
};
// find the total number of (data) rows
int rows = grps.Max(grp => grp.Bars.Length);
// output columns
foreach (var grp in grps) {
Console.Write(grp.Foo + "\t");
}
Console.WriteLine();
// output data
for (int i = 0; i < rows; i++) {
foreach (var grp in grps) {
Console.Write((i < grp.Bars.Length ? grp.Bars[i] : null) + "\t");
}
Console.WriteLine();
}
Marc's answer gives sparse matrix that can't be pumped into Grid directly.
I tried to expand the code from the link provided by Vasu as below:
public static Dictionary<TKey1, Dictionary<TKey2, TValue>> Pivot3<TSource, TKey1, TKey2, TValue>(
this IEnumerable<TSource> source
, Func<TSource, TKey1> key1Selector
, Func<TSource, TKey2> key2Selector
, Func<IEnumerable<TSource>, TValue> aggregate)
{
return source.GroupBy(key1Selector).Select(
x => new
{
X = x.Key,
Y = source.GroupBy(key2Selector).Select(
z => new
{
Z = z.Key,
V = aggregate(from item in source
where key1Selector(item).Equals(x.Key)
&& key2Selector(item).Equals(z.Key)
select item
)
}
).ToDictionary(e => e.Z, o => o.V)
}
).ToDictionary(e => e.X, o => o.Y);
}
internal class Employee
{
public string Name { get; set; }
public string Department { get; set; }
public string Function { get; set; }
public decimal Salary { get; set; }
}
public void TestLinqExtenions()
{
var l = new List<Employee>() {
new Employee() { Name = "Fons", Department = "R&D", Function = "Trainer", Salary = 2000 },
new Employee() { Name = "Jim", Department = "R&D", Function = "Trainer", Salary = 3000 },
new Employee() { Name = "Ellen", Department = "Dev", Function = "Developer", Salary = 4000 },
new Employee() { Name = "Mike", Department = "Dev", Function = "Consultant", Salary = 5000 },
new Employee() { Name = "Jack", Department = "R&D", Function = "Developer", Salary = 6000 },
new Employee() { Name = "Demy", Department = "Dev", Function = "Consultant", Salary = 2000 }};
var result5 = l.Pivot3(emp => emp.Department, emp2 => emp2.Function, lst => lst.Sum(emp => emp.Salary));
var result6 = l.Pivot3(emp => emp.Function, emp2 => emp2.Department, lst => lst.Count());
}
* can't say anything about the performance though.
You can use Linq's .ToLookup to group in the manner you are looking for.
var lookup = data.ToLookup(d => d.TypeCode, d => d.User);
Then it's a matter of putting it into a form that your consumer can make sense of. For instance:
//Warning: untested code
var enumerators = lookup.Select(g => g.GetEnumerator()).ToList();
int columns = enumerators.Count;
while(columns > 0)
{
for(int i = 0; i < enumerators.Count; ++i)
{
var enumerator = enumerators[i];
if(enumator == null) continue;
if(!enumerator.MoveNext())
{
--columns;
enumerators[i] = null;
}
}
yield return enumerators.Select(e => (e != null) ? e.Current : null);
}
Put that in an IEnumerable<> method and it will (probably) return a collection (rows) of collections (column) of User where a null is put in a column that has no data.
I guess this is similar to Marc's answer, but I'll post it since I spent some time working on it. The results are separated by " | " as in your example. It also uses the IGrouping<int, string> type returned from the LINQ query when using a group by instead of constructing a new anonymous type. This is tested, working code.
var Items = new[] {
new { TypeCode = 1, UserName = "Don Smith"},
new { TypeCode = 1, UserName = "Mike Jones"},
new { TypeCode = 1, UserName = "James Ray"},
new { TypeCode = 2, UserName = "Tom Rizzo"},
new { TypeCode = 2, UserName = "Alex Homes"},
new { TypeCode = 3, UserName = "Andy Bates"}
};
var Columns = from i in Items
group i.UserName by i.TypeCode;
Dictionary<int, List<string>> Rows = new Dictionary<int, List<string>>();
int RowCount = Columns.Max(g => g.Count());
for (int i = 0; i <= RowCount; i++) // Row 0 is the header row.
{
Rows.Add(i, new List<string>());
}
int RowIndex;
foreach (IGrouping<int, string> c in Columns)
{
Rows[0].Add(c.Key.ToString());
RowIndex = 1;
foreach (string user in c)
{
Rows[RowIndex].Add(user);
RowIndex++;
}
for (int r = RowIndex; r <= Columns.Count(); r++)
{
Rows[r].Add(string.Empty);
}
}
foreach (List<string> row in Rows.Values)
{
Console.WriteLine(row.Aggregate((current, next) => current + " | " + next));
}
Console.ReadLine();
I also tested it with this input:
var Items = new[] {
new { TypeCode = 1, UserName = "Don Smith"},
new { TypeCode = 3, UserName = "Mike Jones"},
new { TypeCode = 3, UserName = "James Ray"},
new { TypeCode = 2, UserName = "Tom Rizzo"},
new { TypeCode = 2, UserName = "Alex Homes"},
new { TypeCode = 3, UserName = "Andy Bates"}
};
Which produced the following results showing that the first column doesn't need to contain the longest list. You could use OrderBy to get the columns ordered by TypeCode if needed.
1 | 3 | 2
Don Smith | Mike Jones | Tom Rizzo
| James Ray | Alex Homes
| Andy Bates |
#Sanjaya.Tio I was intrigued by your answer and created this adaptation which minimizes keySelector execution. (untested)
public static Dictionary<TKey1, Dictionary<TKey2, TValue>> Pivot3<TSource, TKey1, TKey2, TValue>(
this IEnumerable<TSource> source
, Func<TSource, TKey1> key1Selector
, Func<TSource, TKey2> key2Selector
, Func<IEnumerable<TSource>, TValue> aggregate)
{
var lookup = source.ToLookup(x => new {Key1 = key1Selector(x), Key2 = key2Selector(x)});
List<TKey1> key1s = lookup.Select(g => g.Key.Key1).Distinct().ToList();
List<TKey2> key2s = lookup.Select(g => g.Key.Key2).Distinct().ToList();
var resultQuery =
from key1 in key1s
from key2 in key2s
let lookupKey = new {Key1 = key1, Key2 = key2}
let g = lookup[lookupKey]
let resultValue = g.Any() ? aggregate(g) : default(TValue)
select new {Key1 = key1, Key2 = key2, ResultValue = resultValue};
Dictionary<TKey1, Dictionary<TKey2, TValue>> result = new Dictionary<TKey1, Dictionary<TKey2, TValue>>();
foreach(var resultItem in resultQuery)
{
TKey1 key1 = resultItem.Key1;
TKey2 key2 = resultItem.Key2;
TValue resultValue = resultItem.ResultValue;
if (!result.ContainsKey(key1))
{
result[key1] = new Dictionary<TKey2, TValue>();
}
var subDictionary = result[key1];
subDictionary[key2] = resultValue;
}
return result;
}
I create my selectlist from enum.
[Flags]
public enum Age
{
New_Born = 1,
Toddler = 2,
Preschool = 4,
Kindergarten = 8,
Elementary_School = 16,
Middle_School = 32,
High_School = 64
}
var age = from Age e in Enum.GetValues(typeof(Age))
select new { Id = (int)e, Name = e.ToString().Replace("_", " ") };
I tried both:
var ageList = new SelectList(age, "Id", "Name", (int)Model.Child.Age);
or
var ageList = new SelectList(age, "Id", "Name", Model.Child.Age);
#Html.DropDownListFor(m => m.Child.Age, ageList, "Your Child's Age")
Everything works except the selected value didn't get selected.
EDIT: after hours testing, finally fix it.
chagne Id = (int)e to Id = e.
var age = from Age e in Enum.GetValues(typeof(Age))
select new { Id = e, Name = e.ToString().Replace("_", " ") };
var ageList = new SelectList(age, "Id", "Name", Model.Child.Age);
I just created a similar example and worked out your problem and I believe you have two problems with your code:
In your controller code, you should have your first option, like this:
SelectList selectList = new SelectList(items, "Id", "Name", (int)Qualities.Whatever);
And in your view:
<%= this.Html.DropDownListFor(m => m.List.SelectedValue, this.Model.List, "Qualities") %>
Think about it, why would you pass the SelectList twice? You should pass the selected value and then the list of values.
The fact that I didn't use Razor view engine is irrelevant.
after hours testing, finally fix it. chagne Id = (int)e to Id = e.
var age = from Age e in Enum.GetValues(typeof(Age))
select new { Id = e, Name = e.ToString().Replace("_", " ") };
var ageList = new SelectList(age, "Id", "Name", Model.Child.Age);
I can't get this bit of logic converted into a Linq statement and it is driving me nuts. I have a list of items that have a category and a createdondate field. I want to group by the category and only return items that have the max date for their category.
So for example, the list contains items with categories 1 and 2. The first day (1/1) I post two items to both categories 1 and 2. The second day (1/2) I post three items to category 1. The list should return the second day postings to category 1 and the first day postings to category 2.
Right now I have it grouping by the category then running through a foreach loop to compare each item in the group with the max date of the group, if the date is less than the max date it removes the item.
There's got to be a way to take the loop out, but I haven't figured it out!
You can do something like that :
from item in list
group item by item.Category into g
select g.OrderByDescending(it => it.CreationDate).First();
However, it's not very efficient, because it needs to sort the items of each group, which is more complex than necessary (you don't actually need to sort, you just need to scan the list once). So I created this extension method to find the item with the max value of a property (or function) :
public static T WithMax<T, TValue>(this IEnumerable<T> source, Func<T, TValue> selector)
{
var max = default(TValue);
var withMax = default(T);
var comparer = Comparer<TValue>.Default;
bool first = true;
foreach (var item in source)
{
var value = selector(item);
int compare = comparer.Compare(value, max);
if (compare > 0 || first)
{
max = value;
withMax = item;
}
first = false;
}
return withMax;
}
You can use it as follows :
from item in list
group item by item.Category into g
select g.WithMax(it => it.CreationDate);
UPDATE : As Anthony noted in his comment, this code doesn't exactly answer the question... if you want all items which date is the maximum of their category, you can do something like that :
from item in list
group item by item.Category into g
let maxDate = g.Max(it => it.CreationDate)
select new
{
Category = g.Key,
Items = g.Where(it => it.CreationDate == maxDate)
};
How about this:
private class Test
{
public string Category { get; set; }
public DateTime PostDate { get; set; }
public string Post { get; set; }
}
private void Form1_Load(object sender, EventArgs e)
{
List<Test> test = new List<Test>();
test.Add(new Test() { Category = "A", PostDate = new DateTime(2010, 5, 5, 12, 0, 0), Post = "A1" });
test.Add(new Test() { Category = "B", PostDate = new DateTime(2010, 5, 5, 13, 0, 0), Post = "B1" });
test.Add(new Test() { Category = "A", PostDate = new DateTime(2010, 5, 6, 12, 0, 0), Post = "A2" });
test.Add(new Test() { Category = "A", PostDate = new DateTime(2010, 5, 6, 13, 0, 0), Post = "A3" });
test.Add(new Test() { Category = "A", PostDate = new DateTime(2010, 5, 6, 14, 0, 0), Post = "A4" });
var q = test.GroupBy(t => t.Category).Select(g => new { grp = g, max = g.Max(t2 => t2.PostDate).Date }).SelectMany(x => x.grp.Where(t => t.PostDate >= x.max));
}
Reformatting luc's excellent answer to query comprehension form. I like this better for this kind of query because the scoping rules let me write more concisely.
from item in source
group item by item.Category into g
let max = g.Max(item2 => item2.PostDate).Date
from item3 in g
where item3.PostDate.Date == max
select item3;
I'm trying to write a LINQ query and am having problems. I'm not sure if lambda expressions are the answer or not but I think they may be.
I have two combo boxes on my form: "State" and "Color".
I want to select Widgets from my database based on the values of these two dropdowns.
My widgets can be in one of the following states: Not Started, In Production, In Finishing, In Inventory, Sold. Widgets can have any color in the 'color' table in the database.
The 'state' combobox has selections "Not Sold," "In Production/Finishing", "Not Started," "In Production," "In Finishing," "In Inventory," "Sold." (I hope these are self-explanatory.)
The 'color' dropdown has "All Colors," and a separate item for each color in the database.
How can I create a LINQ query to select the widgets I want from the database based on the dropdowns?
var WidgetStateChoosen = "Sold";
//var WidgetStateChoosen = "All Widgets";
var WidgetColourChoosen = "Orange";
//var WidgetColourChoosen = "All Colours";
var widgetselected = Widgets.Where
(w =>
( (WidgetStateChoosen == "All Widgets") ? (w.WidgetState != WidgetStateChoosen) : (w.WidgetState == WidgetStateChoosen) )
&&
( (WidgetColourChoosen == "All Colours") ? (w.WidgetColour != WidgetColourChoosen) : (w.WidgetColour == WidgetColourChoosen) )
);
Way more code then I wish, but oh well! I wasnt sure I completely understood your state and selectionstate, but I hope my example is still helpful.
[TestMethod]
public void SelectionTest()
{
var userSelections = GetUserSelections("AllColor", (SelectedState[])Enum.GetValues(typeof(SelectedState)));
var inventory = this.GetInventory();
foreach (var currentSelection in userSelections)
{
var selection = currentSelection;
var result = from item in inventory
where (item.Color == selection.Color || selection.Color == "AllColor") &&
this.GetStates(selection.State).Contains(item.State)
select item;
Console.WriteLine("Item selected for selection: Color:{0} SelectedState:{1}", selection.Color, selection.State);
foreach (var item in result)
{
Console.WriteLine("Item Color:{0};Item State:{1}", item.Color, item.State);
}
Console.WriteLine("");
}
}
private IEnumerable<State> GetStates(SelectedState state)
{
var list = new List<State>();
foreach (State currentState in Enum.GetValues(typeof(State)))
{
if (((int)currentState & (int)state) == (int)currentState)
{
list.Add(currentState);
}
}
return list;
}
private IEnumerable<Item> GetInventory()
{
return new List<Item>()
{
new Item() {State = State.NotStarted, Color = "Blue"},
new Item() {State = State.InFinishing, Color = "Red"},
new Item() {State = State.Sold, Color = "Yellow"},
new Item() {State = State.Sold, Color = "Blue"},
new Item() {State = State.InProduction, Color = "Blue"},
new Item() {State = State.InInventory, Color = "Blue"},
};
}
private IEnumerable<UserSelection> GetUserSelections(String color, IEnumerable<SelectedState> states)
{
var list = new List<UserSelection>();
foreach (var state in states)
{
list.Add(new UserSelection() { Color = color, State = state });
}
return list;
}
[Flags]
private enum State
{
NotStarted = 1,
InProduction = 2,
InFinishing = 4,
InInventory = 8,
Sold = 16
}
private enum SelectedState
{
NotSold = State.InInventory, //Where does it map? I assume INInventory even if it doesnt make much sense
InProductionOrFinishing = State.InProduction | State.InFinishing,
NotStarted = State.NotStarted,
InProduction = State.InProduction,
InFinishing = State.InFinishing,
InInventory = State.InInventory,
Sold = State.Sold,
SomeBizarroTrippleState = State.InProduction | State.Sold | State.NotStarted
}
private class UserSelection
{
public String Color { get; set; }
public SelectedState State { get; set; }
}
private class Item
{
public String Color { get; set; }
public State State { get; set; }
}
var query = db.Widgets;
if (stateFilter == "Not sold")
query = query.Where(w => w.State != WidgetState.Sold);
else if (stateFilter == "In Production/Finishing")
query = query.Where(w => w.State == WidgetState.InProduction || w.State == WidgetState.Finishing);
if (colorFilter != "All colors")
query = query.Where(w => w.Color = colorFilter);
(of course you should have a better way of testing the selected value from the combobox, testing on strings is really bad...)