how to build dynamically WPF toolbar? - wpf

Because ToolBarTray provider no itemsSource i'm using Toolbars as place holders but can't get it done. I have made a user control that is placed MainWindow. I used similar thing to build menu as a base for this and frankly i don't know what I'm doing. I use also the same MenuItemViewModel here. But I can't get anything to the toolbar. The menu works perfect.
<UserControl.Resources>
<ui:ToolbarButtonFilterConverter x:Key="converter" />
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Command" Value="{Binding Path=Command}"/>
<Setter Property="Visibility" Value="{Binding Path=Visibility}"/>
<Setter Property="Content" Value="{Binding Path=BitmapName, Converter={x:Static ui:NativeImageResourceConverter.Default }}"/>
</Style>
<HierarchicalDataTemplate DataType="{x:Type menu:MenuItemViewModel}" ItemsSource="{Binding Path=MenuItems}" />
</UserControl.Resources>
<ToolBarTray Grid.Row="0" VerticalAlignment="Center" >
<ToolBar Name="Toolbar1" ItemsSource="{Binding Path=ToolbarItems, Converter={StaticResource converter}, ConverterParameter=Toolbar1}"/>
<!-- here more toolbars as placeholders -->
</ToolBarTray>
</UserControl>
The ToolbarViewModel seems to work ok (bound collections) because in convert below the corret item with 6 child items is returned), but xaml is probably faulty. ui:NativeImageResourceConverter is never called for these toolbar buttons that should get created from MenuItemViewModels.
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
var items = value as ObservableCollection<MenuItemViewModel>;
if (parameter != null && items != null)
{
if (parameter.ToString() == "Toolbar1")
{
return items.Where(i => i.Header == "Toolbar1");
}
//...
}
return null;
}
Menu items are hiearchical and can contains children in MenuItemViewModel:
public class MenuItemViewModel
{
public Visibility Visibility { get; private set; }
public string BitmapName { get; private set; }
public ICommand Command { get; private set; }
private ObservableCollection<MenuItemViewModel> _menuItems;
public ObservableCollection<MenuItemViewModel> MenuItems;
//...
}

Related

Set ContentPresenter ContentTemplate on value change in generated field

I have am attempting to build a tree view where:
1. The TreeViewItems are generated by a list in my model.
2. Each TreeViewItem contains a ComboBox, and a dynamic element whose template I want to change based on the value selected in the ComboBox.
Here is my current xaml code.
<Window x:Class="MyTestWPF.MainWindow"
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:MyTestWPF"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:NodeTypeToTemplateConverter x:Key="NodeTypeToTemplateConverter"/>
<DataTemplate x:Key="Template1">
<TextBlock Text="Template 1" />
</DataTemplate>
<DataTemplate x:Key="Template2">
<TextBlock Text="Template 2" />
</DataTemplate>
<Style x:Key="MyNodeTemplate" TargetType="ContentPresenter">
<Setter Property="ContentTemplate" Value="{StaticResource Template1}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=NodeType}">
<DataTrigger.Value>
<local:NodeTypesEnum>Type1</local:NodeTypesEnum>
</DataTrigger.Value>
<Setter Property="ContentTemplate" Value="{Binding Converter={StaticResource NodeTypeToTemplateConverter}}"/>
</DataTrigger>
</Style.Triggers>
</Style>
<HierarchicalDataTemplate DataType="{x:Type local:MyTreeNode}"
ItemsSource="{Binding Nodes}">
<StackPanel Orientation="Horizontal">
<ComboBox ItemsSource="{Binding Path=GetAvailableNodeType}"
SelectedItem="{Binding Path=NodeType}" />
<ContentPresenter Style="{StaticResource MyNodeTemplate}" Content="{Binding}" />
</StackPanel>
</HierarchicalDataTemplate>
</Window.Resources>
<TreeView x:Name="MyTree" ItemsSource="{Binding MyTreeModel}" />
</Window>
And its code-behind:
using System.Windows;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new
{
MyTreeModel = new MyTreeNode[] {
new MyTreeNode() { Name = "1", Nodes = new MyTreeNode[] { new MyTreeNode() { Name= "2" } } }
}
};
}
}
The tree node type:
namespace MyTestWPF
{
public class MyTreeNode
{
public string Name { get; set; }
public NodeTypesEnum NodeType { get; set; }
public MyTreeNode[] Nodes { get; set; }
public NodeTypesEnum[] GetAvailableNodeType()
{
return new NodeTypesEnum[] { NodeTypesEnum.Type1, NodeTypesEnum.Type2 };
}
}
public enum NodeTypesEnum
{
Type1 = 0,
Type2 = 1
}
}
The Converter (NodeTypeToTemplateConverter) receives the whole ViewModel, and returns the name of the relevant template based on values in the model.
using System;
using System.Globalization;
using System.Windows.Data;
namespace MyTestWPF
{
public class NodeTypeToTemplateConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if((value as MyTreeNode).NodeType == NodeTypesEnum.Type1)
{
return "Template1";
} else
{
return "Template2";
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
The problem is that the above code causes a stack overflow exception. The first item in the TreeView endlessly calls NodeTypeToTemplateConverter's Convert method.
I figured it had to do with the DataTrigger.Value. Setting that to a value different from the default NodeType allows the page to load without overflow, but the moment any ComboBox is set to NodeType1, stack overflow.
I attempted to simply remove the DataTrigger.Value element, but that causes the Converter to never be called at all...
How can I dynamically build the template name based on the value selected by its neighboring ComboBox?
You probably want to use a DataTemplateSelector rather than a converter.
public class ComboBoxItemTemplateSelector : DataTemplateSelector
{
public DataTemplate Template1 { get; set; }
public DataTemplate Template2 { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
//Logic to select template based on 'item' value.
if (item == <template1Value>) return Template1; //TODO: replace <template1Value>
else if (item == <template2Value>) return Template2; //TODO: replace <template2Value>
else return new DataTemplate();
}
}
<local:ComboBoxItemTemplateSelector x:Key="ComboBoxItemTemplateSelector">
<local:ComboBoxItemTemplateSelector.Template1>
<DataTemplate>
<TextBlock Text="" />
</DataTemplate>
</local:ComboBoxItemTemplateSelector.Template1>
<local:ComboBoxItemTemplateSelector.Template2>
<DataTemplate>
<TextBlock Text="" />
</DataTemplate>
</local:ComboBoxItemTemplateSelector.Template2>
</local:ComboBoxItemTemplateSelector>
<ContentPresenter Content="{Binding NodeType}" ContentTemplateSelector="{StaticResource ComboBoxItemTemplateSelector}"/>
I have not fully tested this code, so let me know if you have any issues.
EDIT:
The template selector is only executed when the content changes so this won't work if you use {Binding}. A workaround for this would be to have the DataTemplate content bind to the parent's DataContext.
<DataTemplate>
<TextBlock Text="" DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ContentPresenter}}"/>
</DataTemplate>
If this workaround is not acceptable, there are other ways to do this as well.

Showing same xaml format image inside multiple dataGrid cells by utilising IValueConverter

I have a working solution to convert boolean value into a xaml-image wrapped inside <Viewbox> by using <ContentControl> as follows:
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl Content="{Binding Recommended, Converter={StaticResource BoolImageConverter}}" Height="20"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
But with the above solution the converted image is only shown in the first cell.
How can I properly use <ControlTemplate> or <Control> in this
case?
I have looked into this answer but I'm unable to reproduce a working solution with the Converter.
Example of the xaml-image
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Viewbox x:Key="Symbols.StarIcon">
<Canvas Width="46" Height="44" >
...
</Canvas>
</Viewbox>
</ResourceDictionary>
The Converter idea is from this post:
public class BoolToImage : IValueConverter
{
public Viewbox TrueImage { get; set; }
public Viewbox FalseImage { get; set; }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value is bool))
{
return null;
}
bool b = (bool)value;
if (b)
{
return this.TrueImage;
}
else
{
return this.FalseImage;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Your ViewBox is a control with a key. And control can have only one visual parent. So the first cell monopolizes ViewBox, and others can't use it.
In your case it is better to use CellTemplateSelector property.
First, create custom DataTemplateSelector:
public class TrueFalseSelector : DataTemplateSelector
{
public DataTemplate TrueTemplate { get; set; }
public DataTemplate FalseTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item == null) return null;
var isSomething = ((CustomObjectType) item).CustomBoolProperty;
return isSomething ? this.TrueTemplate
: FalseTemplate;
}
}
Then use it in XAML. Add Selector in Resources somewhere:
<local:TrueFalseSelector x:Key="trueFalseSelector">
<local:TrueFalseSelector.TrueTemplate>
<DataTemplate>
<!-- your true template here -->
</DataTemplate>
</local:TrueFalseSelector.TrueTemplate>
<local:TrueFalseSelector.FalseTemplate>
<DataTemplate>
<!-- your false template here -->
</DataTemplate>
</local:TrueFalseSelector.FalseTemplate>
</local:TrueFalseSelector>
And voila:
<DataGrid.Columns>
<DataGridTemplateColumn CellTemplateSelector="{StaticResource trueFalseSelector}" />
</DataGrid.Columns>
EDIT: you can place DataTemplates in the same dictionary where your ViewBox is right now. Give them a key and just use like this:
<local:TrueFalseSelector x:Key="trueFalseSelector"
FalseTemplate="{StaticResource falseTemplate}"
TrueTemplate="{StaticResource trueTemplate">
Here is just another way you can do this (pure xaml):
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl Style="{StaticResource RecommendedStyle}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<Style TargetType="ContentControl" x:Key="RecommendedStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ViewBox x:Key="True"/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Recommended}" Value="False">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ViewBox x:Key="False"/><!--This is image for false-->
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style>

How to search for a wpf list box item value and highlight the index based on the value?

In my application I would like you highlight an index based on the value. for example:
ArrayList itemsList = new ArrayList();
private void button_Click(object sender, RoutedEventArgs e)
{
itemsList.Add("Coffie");
itemsList.Add("Tea");
itemsList.Add("Orange Juice");
itemsList.Add("Milk");
itemsList.Add("Mango Shake");
itemsList.Add("Iced Tea");
itemsList.Add("Soda");
itemsList.Add("Water");
listBox.ItemsSource = itemsList;
ApplyDataBinding();
}
private void ApplyDataBinding()
{
listBox.ItemsSource = null;
listBox.ItemsSource = itemsList;
}
It does not matter where in the listbox "Orange Juice" is I would like to highlight it based on its value. If the Position change it should be still highlighted. (Not based on the selected index)
If you want to highlight an item based on it's value, then you need to define your own datatemplate for an item and use a converter to provide appropriate brush for the background. Something like that:
<Window.Resources>
<local:TextToBrushConverter x:Key="TextToBrushConverter" />
</Window.Resources>
<Grid>
<ListBox Name="listBox" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" Background="{Binding ., Converter={StaticResource TextToBrushConverter}}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Converter
class TextToBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if ((value as String) == "Orange Juice")
{
return Brushes.Orange;
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
I would recommend that you place the items into a class, think Object Oriented design and then work off of properties (as flags) to give different states.
Then by using Xaml styles to key off those different properties to achieve the affect you are looking for.
Say for example we have an Order class with these properties
public class Order
{
public string CustomerName { get; set; }
public int OrderId { get; set; }
public bool InProgress { get; set; }
}
When an order is marked as in progress (InProgress = true) we want to show red in our list box say for "Alpha" and "Omega" which are in progress:
ListBox Xaml
Here is the Xaml which binds to our data (how you bind is up to you) and shows how to work with Style(s), DataTemplate, and DataTrigger(s) to achieve that:
<ListBox ItemsSource="{StaticResource Orders}"
x:Name="lbOrders">
<ListBox.Resources>
<DataTemplate DataType="{x:Type model:Order}">
<TextBlock Text="{Binding Path=CustomerName}" />
</DataTemplate>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=InProgress}"
Value="True">
<Setter Property="Foreground"
Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.Resources>
</ListBox>
Here is the data setup in the pages's resource Xaml to do that, but it could be created in code behind:
<Window.Resources>
<model:Orders x:Key="Orders">
<model:Order CustomerName="Alpha"
OrderId="997"
InProgress="True" />
<model:Order CustomerName="Beta"
OrderId="998"
InProgress="False" />
<model:Order CustomerName="Omega"
OrderId="999"
InProgress="True" />
<model:Order CustomerName="Zeta"
OrderId="1000"
InProgress="False" />
</model:Orders>
</Window.Resources>
This should give you enough to start on and create a full featured UI.

ContextMenu is not setted by DataTrigger, but it is displayed

I use MVVM mode.
There are two ViewModels:
ClientViewModel and DiskViewModel, ClientViewModel has a collection ObservableCollection<DiskViewModel>.
I want to display their hierarchical relationship and do something via their ContextMenu. I set different ContextMenu via TypeToBooleanConverter in DataTrigger in TreeViewItem like this:
<Style TargetType="{x:Type TreeViewItem}">
<Style.Triggers>
<DataTrigger Value="true" Binding="{Binding Converter={cvt:TypeToBooleanConverter},ConverterParameter={x:Type vm:ClientViewModel}}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Client"/>
</ContextMenu>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
But there is a problem:
If I only set ContextMenu for ClientViewModel via above method, not set ContextMenu for DiskViewModel, it will be show "Client" if right-click on Disk TreeViewItem. But I never set it.
With a picture: this is not I need. I want to nothing if I right-click on Disk TreeViewItem.
Above scene is the simplest. Actually hierarchical relationship is that:
ClientList
|---Client
|---DiskList
|---Disk
|---PartitionList
|---Partition
Different types of item or one type time with different status has different ContextMenu. Enumerate all cases may be a hadr work.
I Need your help.
Code files:
// MainViewModel.cs
using GalaSoft.MvvmLight;
using System.Collections.ObjectModel;
namespace WpfApplication12.ViewModel
{
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
ClientList = new ObservableCollection<ClientViewModel>();
var disk = new DiskViewModel();
disk.Name = "disk1";
var client = new ClientViewModel();
client.Name = "client1";
client.DiskList.Add(disk);
ClientList.Add(client);
}
#region ClientList
public const string ClientListPropertyName = "ClientList";
private ObservableCollection<ClientViewModel> _clientList;
public ObservableCollection<ClientViewModel> ClientList
{
get
{
return _clientList;
}
set
{
if (_clientList == value)
return;
_clientList = value;
RaisePropertyChanged(ClientListPropertyName);
}
}
#endregion // ClientList
}
public class ClientViewModel : ViewModelBase
{
public ClientViewModel()
{
DiskList = new ObservableCollection<DiskViewModel>();
}
#region Name
public const string NamePropertyName = "Name";
private string _name;
public string Name
{
get
{
return _name;
}
set
{
if (_name == value)
return;
_name = value;
RaisePropertyChanged(NamePropertyName);
}
}
#endregion // Name
#region DiskList
public const string DiskListPropertyName = "DiskList";
private ObservableCollection<DiskViewModel> _diskList;
public ObservableCollection<DiskViewModel> DiskList
{
get
{
return _diskList;
}
set
{
if (_diskList == value)
return;
_diskList = value;
RaisePropertyChanged(DiskListPropertyName);
}
}
#endregion // DiskList
}
public class DiskViewModel : ViewModelBase
{
public DiskViewModel()
{
}
#region Name
public const string NamePropertyName = "Name";
private string _name;
public string Name
{
get
{
return _name;
}
set
{
if (_name == value)
return;
_name = value;
RaisePropertyChanged(NamePropertyName);
}
}
#endregion // Name
}
}
.
// MainWindow.xaml
<Window x:Class="WpfApplication12.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:WpfApplication12.ViewModel"
xmlns:cvt="clr-namespace:InfoCore.StreamerConsole.Converters"
WindowStartupLocation="CenterScreen"
Title="MainWindow" Height="350" Width="525"
DataContext="{Binding Source={StaticResource Locator},Path=Main}">
<Grid>
<TreeView Background="AliceBlue" Margin="10"
ItemsSource="{Binding ClientList}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type vm:ClientViewModel}" ItemsSource="{Binding DiskList}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type vm:DiskViewModel}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Style.Triggers>
<DataTrigger Value="true" Binding="{Binding Converter={cvt:TypeToBooleanConverter},ConverterParameter={x:Type vm:ClientViewModel}}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Client"/>
</ContextMenu>
</Setter.Value>
</Setter>
</DataTrigger>
<!--<DataTrigger Value="true" Binding="{Binding Converter={cvt:TypeToBooleanConverter},ConverterParameter={x:Type vm:DiskViewModel}}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Disk"/>
</ContextMenu>
</Setter.Value>
</Setter>
</DataTrigger>-->
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
</Grid>
</Window>
.
// ToBooleanConverter.cs
[MarkupExtensionReturnType(typeof(TypeToBooleanConverter))]
[ValueConversion(typeof(Type), typeof(bool))]
public class TypeToBooleanConverter : MarkupExtension, IValueConverter
{
private static TypeToBooleanConverter _converter = null;
public override object ProvideValue(IServiceProvider serviceProvider)
{
return _converter ?? (_converter = new TypeToBooleanConverter());
}
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (value == null)
return Binding.DoNothing;
return Type.Equals(value.GetType(), parameter);
}
public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
return value.Equals(true) ? parameter : Binding.DoNothing;
}
}

How to define MenuItems with Icons as Templates in App.xaml

In my apps, I have a lot context menus. Most of them contain a lot of standard entries such as menu items for the cut, copy and the paste command. Every menu has an attached icon.
How do I define a style for each type of MenuItem which is application wide available? The following xaml is principally what I’m looking for, however the declaration of the image is invalid (if by hazard an instance of the style is used at more than one position at the same time, the image will not be shown).
<Style x:Key="CutMenuItem_Style" TargetType="{x:Type MenuItem}" >
<Setter Property="Command" Value="Cut"/>
<Setter Property="Header" Value="Cut"/>
<Setter Property="Icon" >
<Setter.Value>
<Image Source="/image/cut_16_16.png" Stretch="None" />
</Setter.Value>
</Setter>
</Style>
How do you do this? Do you declare a ControlTemplate for each menu-type?
Please note: I understand why the above xaml does not work as expected. I’m interested in an alternative and reliable way to do the same as I have intended with the above code.
I'm not sure if this will work or not (haven't tested it), but I'm intrigued by the possibility that you could some something like this:
class MyMenuItem
{
public ICommand Command { get; set; }
public string Header { get; set; }
public ImageSource ImageSource { get; set; }
}
var cutMenuItem = new MyMenuItem()
{
Command = ...,
Header = "Cut",
ImageSource = ...
};
And then use DataTemplates:
<DataTemplate DataType="{x:Type local:MyMenuItem}">
<MenuItem Command="{Binding Command}" Header="{Binding Header}"
Icon="{Binding ImageSource}" />
</MenuItem>
</DataTemplate>
And then your menu:
<Menu ItemsSource="{Binding ListOfMyMenuItems}" />
A possibility is to use a IValueConverter which converts RoutedCommands to Images. The IValueConverter can be used then in the global styles.
The XAML looks as follows:
<Style x:Key="MenuItemBase_Style" TargetType="{x:Type MenuItem}">
<Setter Property="Icon" Value="{Binding Command,Converter={StaticResource CommandImage_ValueConverter},RelativeSource={RelativeSource Mode=Self}}"/>
</Style>
<Style x:Key="CutMenuItem_Style" BasedOn="{StaticResource MenuItemBase_Style}" TargetType="{x:Type MenuItem}" >
<Setter Property="Command" Value="Cut"/>
</Style>
<Style x:Key="CopyMenuItem_Style" BasedOn="{StaticResource MenuItemBase_Style}" TargetType="{x:Type MenuItem}" >
<Setter Property="Command" Value="Copy"/>
</Style>
<Style x:Key="AnotherMenuItem_Style" ... />
The IValueConverter is simple but can be extended also for other things. I have written it so, that you can provide a Style as a parameter. This is usefull if you want to manipulate the returned Image.
public class CommandImageValueConverter : IValueConverter{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
if (value == null) return null;
var cmd = value as RoutedCommand;
if (null != cmd) {
var uri = new Uri("/YourComponent;component/Image/" + cmd.Name + "_16_16.png", UriKind.Relative);
return new Image() { Stretch = Stretch.None ,Source=Load(uri),Style=parameter as Style};
}
throw new NotImplementedException("Conversion from " + value.GetType().Name + " is currently not supported");
}
public static ImageSource Load(Uri uri) {
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = uri;
bi.EndInit();
return bi;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
throw new NotImplementedException();
}
}
The IValueConverter must be also be declared once:
<yourNamespace:CommandImageValueConverter x:Key="CommandImage_ValueConverter"/>
Hope this helps someone else.

Resources