Toby Smith Toby Smith - 29 days ago 8
C# Question

Why is null being assigned to this variable?

So I've just discovered the null coalescing ternary operator but I can't seem to figure out why my variable is still being set to null in the line of code below.

MenuItem parent = (treeView.SelectedItem ?? treeView.Items[0]) as MenuItem;

The object
does have multiple items.

No matter if the
has a selected item or not the variable is always null.

Any help would be appreciated, thanks :)

Answer Source

treeView.SelectedItem may or may not be null, but it's never a MenuItem.

treeView.Items[0] may or may not be null, but it's never a MenuItem.

This expression...

(treeView.SelectedItem ?? treeView.Items[0])

...returns the value of treeView.SelectedItem if that value isn't null. If that value is null, the expression returns treeView.Items[0]. Probably better to say "it returns the first non-null operand".

Whichever of those you get, you then use as to try to cast it to a MenuItem. The cast never succeeds, because the actual object you're casting can never be cast to Menuitem.

as returns null when the cast is not possible.

So you always get null.

When you get a situation like this, put in a breakpoint and hover the mouse over all the operands for the expression. Once you know what the operands really are, you can select subexpressions like (treeView.SelectedItem ?? treeView.Items[0]) and hover over those. If you have any questions, don't just try to stare down the code and sweat it out from first principles like Bertrand Russell. Looking at the values in the debugger will provide critical information you'd never think of.


But your real problem is that you have, in some way I haven't identified, populated a WPF TreeView with MenuItems, and you want to get the selected menu item back out. I've tried to reproduce what you did, and the Items collection on my treeview is full of MenuItems, but you say you're seeing TreeViewItems. So I'm not sure what's going on.

This strikes me as a bad way to populate a TreeView in any case. I'd suggest a collection of a mini-viewmodel class, bound to the TreeView's ItemsSource property. There are plenty of examples of this on Stack Overflow. That's the way WPF wants you to do it, and I've found that WPF is extremely unfriendly if you don't do things the way it wants you to.