How to play the drop failed animation in ScalaFX/JavaFX 2? - macos

In ScalaFX if I drop a TreeCell onto a control other than the containing TreeView then a short animation is played showing the dragged item returning to its original position.
The same happens if I drop the TreeCell outside of the application - e.g. onto the desktop.
If I drop the TreeCell onto the containing TreeView in a location that shouldn't be accepted I want the same animation to play, but setting:
event.dropCompleted = false
isn't enough to produce this effect.
Is there a way to play the drop failed animation from inside the TreeCell's onDragDropped event handler?
Edit
Added code sample as requested. Drag an entry and drop it outside the control and you will see the drop failed animation. Drag an entry and drop it below the list and the animation doesn't play. The question is how to make the animation play in the second case.
import scalafx.application.JFXApp
import scalafx.scene.Scene
import scalafx.scene.paint.Color
import scalafx.scene.layout.Pane
import scalafx.Includes._
import scalafx.scene.input.{TransferMode, DataFormat, DragEvent, MouseEvent}
import scalafx.scene.control._
import javafx.scene.control.{TreeItem => jfxTreeItem}
import java.nio.ByteBuffer
import java.util
import scalafx.beans.value.ObservableValue
class StringRootItem(text: String) extends TreeItem[String](text) {
override def toString() = text
}
class StringTreeItem(text: String) extends TreeItem[String](text) {
override def toString() = text
}
object DragAndDropControl {
def apply(rootNodeName: String, entries: List[String]): DragAndDropControl = {
val rootItem = new StringRootItem(rootNodeName)
rootItem.setExpanded(true)
val children = rootItem.getChildren
entries.foreach(entry => {
children.add(new StringTreeItem(entry))
})
new DragAndDropControl(rootItem)
}
}
class DragAndDropControl(rootItem: StringRootItem) extends TreeView[String](rootItem) {
showRoot = false
cellFactory = (tree: TreeView[String]) => {
new StringDragAndDropCell(tree)
}
object StringDragAndDropCell {
val customFormat: DataFormat = new DataFormat("string.entry.custom")
var transferItem: TreeItem[String] = null
def toBuffer(entry: String): ByteBuffer = ByteBuffer.allocate(10)
def fromBuffer(buffer: ByteBuffer): String = null
}
class StringDragAndDropCell(tree: TreeView[String]) extends TreeCell[String] {
import StringDragAndDropCell._
private var stringEntry: String = null
onDragDetected = (event: MouseEvent) => {
val db = startDragAndDrop(TransferMode.MOVE)
import scala.collection.JavaConversions._
if ((treeItem ne null) && (treeItem.value ne null) && (treeItem.value.getValue ne null)) {
transferItem = treeItem.value
val content: Map[javafx.scene.input.DataFormat, AnyRef] = Map(customFormat.delegate -> toBuffer(transferItem.value()))
val contentMap: util.Map[javafx.scene.input.DataFormat, AnyRef] = mapAsJavaMap(content)
db.setContent(contentMap)
}
event.consume()
}
onDragOver = (event: DragEvent) => {
val db = event.getDragboard
if (db.hasContent(customFormat))
event.acceptTransferModes(TransferMode.MOVE)
event.consume()
}
onDragDone = (event: DragEvent) => {
if (event.transferMode == TransferMode.MOVE)
event.dragboard.clear()
event.consume()
}
onDragDropped = (event: DragEvent) => {
val db = event.getDragboard
var success = false
if (db.hasContent(customFormat))
success = stringEntry ne null
if (success)
if (event.gestureSource != event.delegate.getGestureTarget) {
treeItem().getParent.getChildren.removeAll(transferItem)
treeItem().getParent.getChildren.add(index(), transferItem)
}
event.dropCompleted = success
event.consume()
}
/*
* Change handler for the treeItem property.
*
* The treeItem property is set by JavaFX after construction and at any time when the cell is recycled for UI virtualization.
*
* The text property must be updated when the treeItem is set in order for the cell to render correctly (without this the cell will appear blank.)
*/
super.treeItem.onChange((observable: ObservableValue[jfxTreeItem[String], jfxTreeItem[String]], oldValue: jfxTreeItem[String], newValue: jfxTreeItem[String]) => {
if (newValue ne null) {
stringEntry = newValue.getValue
text = stringEntry
}
else
stringEntry = null
})
override def toString(): String = {
if (stringEntry == null)
null
else
s"ScalaFX string tree cell ${stringEntry.toString}"
}
}
}
object TestDragAndDrop extends JFXApp
{
println("javafx.runtime.version: " + System.getProperties.get("javafx.runtime.version"))
println("java.runtime.version: " + System.getProperties.get("java.runtime.version"))
stage = new JFXApp.PrimaryStage {
title = "Test Drag and Drop"
width = 600
height = 472
scene = new Scene {
fill = Color.LIGHTGREEN
root = new Pane {
content = DragAndDropControl("Numbers", List("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"))
}
}
}
}

Related

How to create two scenes in scalafx

I am new to creating GUI using scalafx. I am trying to create two scenes with the following code but getting some error
import com.sun.glass.ui.Application
import scalafx.event.ActionEvent
import scalafx.event.EventHandler
import scalafx.scene.Scene
import scalafx.scene.control.Button
import scalafx.scene.control.Label
import scalafx.scene.layout.StackPane
import scalafx.scene.layout.VBox
import scalafx.stage.Stage
class example extends Application {
var scene1: Scene = null
var scene2: Scene = null
override def start(primaryStage: Stage): Unit = { primaryStage.setTitle("My First JavaFX GUI")
//Scene 1
val label1 = new Label("This is the first scene")
val button1 = new Button("Go to scene 2"){
onAction = (e: ActionEvent) => {
primaryStage.setScene(scene2)
}
}
val layout1 = new VBox(20)
layout1.getChildren.addAll(label1, button1)
scene1 = new Scene(layout1, 300, 250)
//Scene 2
val label2 = new Label("This is the second scene")
val button2 = new Button("Go to scene 1") {
onAction = (e: ActionEvent) => {
primaryStage.setScene(scene1)
}
}
val layout2 = new VBox(20)
layout2.getChildren.addAll(label2, button2)
scene2 = new Scene(layout2, 300, 250)
primaryStage.setScene(scene1)
primaryStage.show()
}
}
The error is:
found : scalafx.event.ActionEvent => Unit
[error] required: javafx.event.EventHandler[javafx.event.ActionEvent]
[error] onAction = (e: ActionEvent) => {}
How can I declare the action events to switch between the scenes?
It would be really helpful if anyone can help
In ScaleFX, your first troubleshooting is to check if you included the ScaleFX implicit conversion magic:
import scalafx.Includes._
In your case, that will fix the issue with the action handler.
Additionally, you should not use com.sun packages neither in ScalaFX nor in JavaFX code. In ScalaFX you should use JFXApp3 instead. Here is your code corrected to use JFXApp3 with some minor corrections:
import scalafx.Includes._
import scalafx.application.JFXApp3
import scalafx.application.JFXApp3.PrimaryStage
import scalafx.event.{ActionEvent, EventHandler}
import scalafx.scene.Scene
import scalafx.scene.control.{Button, Label}
import scalafx.scene.layout.VBox
import scalafx.stage.Stage
object CreteTwoScenes1App extends JFXApp3 {
var scene1: Scene = _
var scene2: Scene = _
override def start(): Unit = {
stage = new PrimaryStage {
title = "My First JavaFX GUI"
}
// Scene 1
val label1 = new Label("This is the first scene")
val button1 = new Button("Go to scene 2") {
onAction = (e: ActionEvent) => {
stage.setScene(scene2)
}
}
val layout1 = new VBox(20)
layout1.children ++= Seq(label1, button1)
scene1 = new Scene(layout1, 300, 250)
// Scene 2
val label2 = new Label("This is the second scene")
val button2 = new Button("Go to scene 1") {
onAction = (e: ActionEvent) => {
stage.setScene(scene1)
}
}
val layout2 = new VBox(20)
layout2.children ++= Seq(label2, button2)
scene2 = new Scene(layout2, 300, 250)
stage.setScene(scene1)
}
}
You can also rewrite that in more idiomatic ScalaFX builder style. Using Scala 3 can make it much more compact too (no curly braces needed):
import scalafx.Includes.*
import scalafx.application.JFXApp3
import scalafx.scene.Scene
import scalafx.scene.control.{Button, Label}
import scalafx.scene.layout.VBox
object CreteTwoScenes2App extends JFXApp3:
override def start(): Unit =
lazy val scene1: Scene = new Scene(300, 200):
root = new VBox(20):
children = Seq(
new Label("This is the first scene"),
new Button("Go to scene 2"):
onAction = () => stage.setScene(scene2)
)
lazy val scene2: Scene = new Scene(300, 200):
root = new VBox(20):
children = Seq(
new Label("This is the second scene"),
new Button("Go to scene 1"):
onAction = () => stage.setScene(scene2)
)
stage = new JFXApp3.PrimaryStage:
title = "My First JavaFX GUI"
scene = scene1

Wren class does not implement a field

I'm trying to learn how to use Dome and Wren. To do this I've started working on a simple Flappy Bird clone.
The problem I'm having is that I get the error message
Bird does not implement bird_idle
It then points to line 63 in my main class which is shown below:
class Main {
resources=(value){ _resources = value }
bird=(value){ _bird = value }
construct new() {
_resources = Resources.new()
_bird = Bird.new(_resources.birdIdle, _resources.birdFlap, _resources.obstacleTile.width * 2, _resources.obstacleTile.height * 4, 10, 4)
}
init() {}
update() {}
draw(alpha) {
Canvas.cls()
Canvas.draw(_bird.bird_idle, _bird.center.x, _bird.center.y) <-- this is line 63
}
}
var Game = Main.new()
Since I'm new to Wren I don't quite understand what this means seeing as if you look at my bird class below, I should be implementing bird_idle. So what am I doing wrong?
class Bird {
bird_idle=(value){ _bird_idle = value } <-- Right?
bird_flap=(value){ _bird_flap = value }
center=(value){ _center = value }
gravity=(value){ _gravity = value }
force=(value){ _force = value }
velocity=(value){ _velocity = value }
velocityLimit=(value){ _velocityLimit = value }
isGameRunning=(value){ _isGameRunning = value }
construct new(idle, flap, horizontalPosition, verticalPosition, drag, jumpForce) {
_bird_idle = idle
_bird_flap = flap
_center = Vector.new(horizontalPosition + (idle.width * 0.5), verticalPosition + (idle.height*0.5))
_gravity = drag
_force = jumpForce
_velocityLimit = 1000
_isGameRunning = true
}
jump() {
_velocity = -_force
}
isTouchingCeiling() {
var birdTop = _center.y - (_bird_idle.height * 0.5)
if(birdTop < 0) {
return true
}
return false
}
isTouchingGround() {
var birdBottom = _center.y + (_bird_idle.height * 0.5)
if(birdBottom > height) {
return true
}
return false
}
}
You forgot to add the getter:
class Bird {
construct new(idle) {
_bird_idle = idle
}
bird_idle=(value){_bird_idle = value }
bird_idle{_bird_idle} // You need this if you want to access the field _bird_idle.
}
var my_bird = Bird.new("Idle")
my_bird.bird_idle = "Not Idle"
System.print(my_bird.bird_idle) // Output: Not Idle

Jetpack Compose Observe mutableStateOf in ViewModel

I have a need to update the user profile switch
ViewModel
class ProfileViewModel : BaseViewModel() {
var greet = mutableStateOf(user.pushSetting.greet)
var message = mutableStateOf(user.pushSetting.message)
var messageDetails = mutableStateOf(user.pushSetting.messageDetails)
var follow = mutableStateOf(user.pushSetting)
var like = mutableStateOf(user.pushSetting.like)
var comment = mutableStateOf(user.pushSetting.comment)
fun updateUser() {
println("--")
}
}
2.Composable
#Composable
fun SettingCard(viewModel: ProfileViewModel) {
Lists {
Section {
TextRow(text = "手机号码") { }
TextRow(text = "修改密码", line = false) { }
}
Section {
SwitchRow(text = "新好友通知", checkedState = viewModel.greet)
SwitchRow(text = "新消息通知", checkedState = viewModel.message)
SwitchRow(text = "消息显示详细", line = false, checkedState = viewModel.messageDetails)
}
}
}
3.SwitchRow
#Composable
fun SwitchRow(text: String, line: Boolean = true, checkedState: MutableState<Boolean>) {
ListItem(
text = { Text(text) },
trailing = {
Switch(
checked = checkedState.value,
onCheckedChange = { checkedState.value = it },
colors = SwitchDefaults.colors(checkedThumbColor = MaterialTheme.colors.primary)
)
}
)
}
How can I observe the change of the switch and call updateUser() in ViewModel
I know this is a way, but it is not ideal. The network update will be called every time it is initialized. Is there a better solution?
LaunchedEffect(viewModel.greet) {
viewModel.updateUser()
}
The best solution for this would be to have unidirectional flow with SwitchRow with a lambda as #Codecameo advised.
But if you want to observe a MutableState inside your Viewmodel you can use snapshotFlows as
var greet: MutableState<Boolean> = mutableStateOf(user.pushSetting.greet)
init {
snapshotFlow { greet.value }
.onEach {
updateUser()
}
.launchIn(viewModelScope)
//...
}
Create a Flow from observable Snapshot state. (e.g. state holders
returned by mutableStateOf.) snapshotFlow creates a Flow that runs
block when collected and emits the result, recording any snapshot
state that was accessed. While collection continues, if a new Snapshot
is applied that changes state accessed by block, the flow will run
block again, re-recording the snapshot state that was accessed. If the
result of block is not equal to the previous result, the flow will
emit that new result. (This behavior is similar to that of
Flow.distinctUntilChanged.) Collection will continue indefinitely
unless it is explicitly cancelled or limited by the use of other Flow
operators.
Add a callback lamba in SwitchRow and call it upon any state change
#Composable
fun SettingCard(viewModel: ProfileViewModel) {
Lists {
Section {
TextRow(text = "手机号码") { }
TextRow(text = "修改密码", line = false) { }
}
Section {
SwitchRow(text = "新好友通知", checkedState = viewModel.greet) {
viewModel.updateUser()
}
SwitchRow(text = "新消息通知", checkedState = viewModel.message) {
viewModel.updateUser()
}
SwitchRow(text = "消息显示详细", line = false, checkedState = viewModel.messageDetails) {
viewModel.updateUser()
}
}
}
}
#Composable
fun SwitchRow(
text: String,
line: Boolean = true,
checkedState: MutableState<Boolean>,
onChange: (Boolean) -> Unit
) {
ListItem(
text = { Text(text) },
trailing = {
Switch(
checked = checkedState.value,
onCheckedChange = {
onChange(it)
checkedState.value = it
},
colors = SwitchDefaults.colors(checkedThumbColor = MaterialTheme.colors.primary)
)
}
)
}
Another approach:
You can keep MutableStateFlow<T> in your viewmodel and start observing it in init method and send a value to it from SwitchRow, like viewModel.stateFlow.value = value.
Remember, MutableStateFlow will only trigger in the value changes. If you set same value twice it will discard second value and will execute for first one.
val stateFlow = MutableStateFlow<Boolean?>(null)
init {
stateFlow
.filterNotNull()
.onEach { updateUser() }
.launchIn(viewModelScope)
}
In switchRow
viewmodel.stateFlow.value = !(viewmodel.stateFlow.value?: false)
This could be one potential solution. You can implement it in your convenient way.

XUnit Test for ViewComponent returns null result?

I am trying to test my ViewComponent with XUnit.
When I debug through the component and set a break point right before it returns the Component View, the model is set.
Here is the simple model I am returning.
public class IntDashMakeRecAssgnmntsPoRespMngrVM
{
public IEnumerable<Audit> Audits { get; set; }
}
And I am trying to assert the Audits.Count() is greater than 0.
Here is my View Component:
public class IntDashMakeRecAssgnmntsPoRespMngrViewComponent : ViewComponent
{
private IAuditRepository _auditRepo;
private IExternalRepository _externalRepo;
public IntDashMakeRecAssgnmntsPoRespMngrViewComponent(IAuditRepository auditRepo,
IExternalRepository externalRepo)
{
_auditRepo = auditRepo;
_externalRepo = externalRepo;
}
public IViewComponentResult Invoke()
{
ClaimsPrincipal user = HttpContext.Request.HttpContext.User;
short staffId = short.Parse(user.Claims.Single(c => c.Type == "StaffId").Value);
// Get all Internal Audits that are not closed and not completed
var audits = _auditRepo.Audits
.Include(a => a.Findings).ThenInclude(f => f.Recommendations).ThenInclude(r => r.Assignments)
.Where(a => a.StatusID != 3 && a.StatusID != 11);
var external = _externalRepo.ExternalRecords;
audits = audits.Where(a => !external.Any(e => e.AuditID == a.AuditID));
if (User.IsInRole("PAG_SPEC") && !User.IsInRole("PAG_ADMIN_INT"))
{
audits = audits.Where(a =>
a.Assignments.Any(assn => assn.AssignmentAuditId == a.AuditID
&& assn.AssignmentRoleId == 2 && assn.AssignmentStaffId == staffId));
}
// Where audit has a recommendation without an assigned PO Authorizer
// OR without an assigned Responsible Manager (Rec Level).
List<Audit> auditsToAssign = new List<Audit>();
foreach (Audit audit in audits)
{
foreach (Finding finding in audit.Findings)
{
foreach (Recommendation rec in finding.Recommendations)
{
if (!rec.Assignments.Any(asgn => asgn.AssignmentRoleId == 15)
|| !rec.Assignments.Any(asgn => asgn.AssignmentRoleId == 26)
)
{
auditsToAssign.Add(rec.Finding.Audit);
break;
}
}
}
}
IntDashMakeRecAssgnmntsPoRespMngrVM intDashMakeRecAssgnmntsPoRespMngrVM =
new IntDashMakeRecAssgnmntsPoRespMngrVM
{
Audits = auditsToAssign
};
return View("/Views/InternalAudit/Components/Dashboard/IntDashMakeRecAssgnmntsPoRespMngr/Default.cshtml", intDashMakeRecAssgnmntsPoRespMngrVM);
}
}
When I get to this line in debugging and break to inspect, I have 1 Audit which I want:
return View("/Views/InternalAudit/Components/Dashboard/IntDashMakeRecAssgnmntsPoRespMngr/Default.cshtml", intDashMakeRecAssgnmntsPoRespMngrVM);
Now here is my Unit Test:
[Fact]
public void ReturnsAudit_1Finding_1Rec_1Asgn_PONeeded_RespMnrAssigned()
{
// Arrange
var audits = new Audit[]
{
new Audit { AuditID = 1 }
};
var findings = new Finding[]
{
new Finding{ Audit = audits[0], FindingId = 1 } // 1 Finding
};
var recommendations = new List<Recommendation>()
{
new Recommendation // 1 Rec
{
Finding = findings[0],
Assignments = new List<Assignment>()
{
// PO Authorizor
new Assignment { AssignmentRoleId = 15 }
// No Responsible Manager
}
}
};
audits[0].Findings = findings;
findings[0].Recommendations = recommendations;
Mock<IAuditRepository> mockAuditRepo = new Mock<IAuditRepository>();
mockAuditRepo.Setup(m => m.Audits).Returns(audits.AsQueryable());
Mock<IExternalRepository> mockExternalRepo = new Mock<IExternalRepository>();
mockExternalRepo.Setup(m => m.ExternalRecords).Returns(
new External[0].AsQueryable()
);
// Act
var component = new IntDashMakeRecAssgnmntsPoRespMngrViewComponent(
mockAuditRepo.Object, mockExternalRepo.Object);
component.ViewComponentContext = new ViewComponentContext();
component.ViewComponentContext.ViewContext.HttpContext = TestContext;
var result =
component.Invoke() as IntDashMakeRecAssgnmntsPoRespMngrVM;
int auditCount = (result).Audits.Count();
// Assert
Assert.Equal(1, auditCount);
}
Why is result null on this line?
var result =
component.Invoke() as IntDashMakeRecAssgnmntsPoRespMngrVM;
I also tried this first and it is still null:
ViewComponentResult result =
component.Invoke() as ViewComponentResult;
int auditCount =
((IntDashMakeRecAssgnmntsPoRespMngrVM)result.Model).Audits.Count();
I figured it out.
I wasn't casting the result to the right type.
I had this:
ViewComponentResult result =
component.Invoke() as ViewComponentResult;
int auditCount =
((IntDashMakeRecAssgnmntsPoRespMngrVM)result.Model).Audits.Count();
It should be this:
var result =
component.Invoke() as ViewViewComponentResult;
int auditCount =
((IntDashMakeRecAssgnmntsPoRespMngrVM)result.ViewData.Model).Audits.Count();
ViewViewComponentResult instead of ViewComponentResult.

LINQ query and lambda expressions

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...)

Resources