Some collections such as ItemCollection implement IEnumerable but do not implement IEnumerable<Type>, DataTable.Rows is another example. If you want to use LINQ extensions such as Any, All, First, etc. you can use Cast<Type> or OfType<Type> to convert them to an IEnumerable<Type>. Then you can use the LINQ extensions.
Here is an example. Start a new Visual Basic project called OfType. Make it a WPF C# application.
We will create a context menu, then use LINQ to see if it contains a particular menu item when the menu is opened. Here is the XAML and code behind without the conversion to IEnumerable<Type>. You can see it will not build.
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:OfType"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
ContextMenuOpening="Window_ContextMenuOpening"
Title="MainWindow" Height="450" Width="800">
<Window.ContextMenu>
<ContextMenu>
<MenuItem Header="One"/>
<MenuItem Header="Two"/>
<MenuItem Header="Three"/>
</ContextMenu>
</Window.ContextMenu>
</Window>
using System.Linq;
public partial class MainWindow : Window
{
public MainWindow()
InitializeComponent();
}
private void Window_ContextMenuOpening(object sender, ContextMenuEventArgs e)
Window w = sender as Window;
Exists = cm.Items.Any(mi => mi.Header.ToString() == "Two");
}
}
There are two ways to fix the problem. Cast<Type> and OfType<Type>. The Cast method will raise an InvalidCast exception if any of the members of the collection cannot be cast. The OfType method will only return the members that can be cast. I will use OfType. Replace the line starting with Exists.
Exists = cm.Items.OfType<MenuItem>().Any(mi => mi.Header.ToString() == "Two");
Menu item 'Two' does exist
No comments:
Post a Comment