public class MainViewModel
{
public MainViewModel()
{
var iconGeometry = Geometry.Parse("M150 0 L75 200 L225 200 Z");
OpenFiles =
new ObservableCollection<File>()
{
new File { IconGeometry = iconGeometry, Filename = "Document.docx" },
new File { IconGeometry = iconGeometry, Filename = "Evidence.xlsx" }
};
ActiveRecords =
new ObservableCollection<Record>()
{
new Record { RecordIconGeometry = iconGeometry, Name = "The First Record" }
};
}
public ObservableCollection<File> OpenFiles { get; set; }
public ObservableCollection<Record> ActiveRecords { get; set; }
}
Based on the MainViewModel
, I would like to create a ContextMenu
that combines one custom item and items from both the OpenFiles
and the ActiveRecords
collection.
<ContextMenu>
<ContextMenu.Resources>
<CollectionViewSource x:Key="ActiveRecordsCollectionSource"
Source="{Binding ActiveRecords}" />
<CollectionViewSource x:Key="OpenFileCollectionSource"
Source="{Binding OpenFiles}" />
<DataTemplate DataType="{x:Type local:File}">
<TextBlock><Run Text="Close " /><Run Text="{Binding FileName}" /></TextBlock>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Record}">
<TextBlock><Run Text="Close " /><Run Text="{Binding Label}" /></TextBlock>
</DataTemplate>
</ContextMenu.Resources>
<ContextMenu.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource ActiveRecordsCollectionSource}}" />
<Separator />
<CollectionContainer Collection="{Binding Source={StaticResource OpenFileCollectionSource}}" />
<Separator />
<MenuItem Header="Close All">
<MenuItem.Icon>
<Path Width="16"
Height="16"
Fill="Black"
Stretch="Uniform"
Data="M10.185,1.417c-4.741,0-8.583,3.842-8.583,8.583c0,4.74,3.842,8.582,8.583,8.582S18.768,14.74,18.768,10C18.768,5.259,14.926,1.417,10.185,1.417 M10.185,17.68c-4.235,0-7.679-3.445-7.679-7.68c0-4.235,3.444-7.679,7.679-7.679S17.864,5.765,17.864,10C17.864,14.234,14.42,17.68,10.185,17.68 M10.824,10l2.842-2.844c0.178-0.176,0.178-0.46,0-0.637c-0.177-0.178-0.461-0.178-0.637,0l-2.844,2.841L7.341,6.52c-0.176-0.178-0.46-0.178-0.637,0c-0.178,0.176-0.178,0.461,0,0.637L9.546,10l-2.841,2.844c-0.178,0.176-0.178,0.461,0,0.637c0.178,0.178,0.459,0.178,0.637,0l2.844-2.841l2.844,2.841c0.178,0.178,0.459,0.178,0.637,0c0.178-0.176,0.178-0.461,0-0.637L10.824,10z" />
</MenuItem.Icon>
</MenuItem>
</CompositeCollection>
</ContextMenu.ItemsSource>
</ContextMenu>
How can I style the items to show both the icon and the name ? If I need ItemContainerStyle
to set the icon , how to change the binding path ( IconGeometry vs. RecordIconGeometry ) based on the Object Type ?
If I need
ItemContainerStyle
to set the icon, how to change the binding path (IconGeometry
vs.RecordIconGeometry
) based on the Object Type?
You could use a converter that returns the appropriate object:
<ContextMenu>
<ContextMenu.Resources>
...
<local:Converter x:Key="conv" />
</ContextMenu.Resources>
<ContextMenu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Icon" Value="{Binding Path=., Converter={StaticResource conv}}" />
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
public class Converter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
File file = value as File;
if (file != null)
return file.IconGeometry;
Record record = value as Record;
if (record != null)
return record.RecordIconGeometry;
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
I am afraid there is no way to call the GetType()
method or use the as
operator in XAML though.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.