I'm following the example here of binding a MenuItem
to a data object.
我正在遵循将MenuItem绑定到数据对象的示例。
<Menu Grid.Row="0" KeyboardNavigation.TabNavigation="Cycle"
ItemsSource="{Binding Path=MenuCommands}">
<Menu.ItemContainerStyle>
<Style>
<Setter Property="MenuItem.Header" Value="{Binding Path=DisplayName}"/>
<Setter Property="MenuItem.ItemsSource" Value="{Binding Path=Commands}"/>
<Setter Property="MenuItem.Command" Value="{Binding Path=Command}"/>
<Setter Property="MenuItem.Icon" Value="{Binding Path=Icon}"/>
</Style>
</Menu.ItemContainerStyle>
</Menu>
It all works swimmingly except the MenuItem
's icon shows up as the string System.Drawing.Bitmap
. The bitmap in question is returned by the data object from a compiled resource.
除了MenuItem的图标显示为字符串System.Drawing.Bitmap之外,它都可以游动。有问题的位图由数据对象从已编译的资源返回。
internal static System.Drawing.Bitmap folder_page
{
get
{
object obj = ResourceManager.GetObject("folder_page", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
What am I doing wrong?
我究竟做错了什么?
5 个解决方案
#1
5
WPF works with ImageSource
s, not System.Drawing
classes. You'll need to bind to an ImageSource
. You could use a converter to convert your Bitmap
to an ImageSource
, or you could ditch the resources and do things differently.
WPF适用于ImageSources,而不适用于System.Drawing类。您需要绑定到ImageSource。您可以使用转换器将Bitmap转换为ImageSource,或者您可以放弃资源并以不同方式执行操作。
#2
9
Kent (of course) has the right answer. But I thought I would go ahead and post the code for the converter that converts from the System.Drawing.Bitmap (Windows Forms) to a System.Windows.Windows.Media.BitmapSource (WPF) ... as this is a common problem/question.
肯特(当然)有正确的答案。但我想我会继续发布转换器的代码,该转换器从System.Drawing.Bitmap(Windows窗体)转换为System.Windows.Windows.Media.BitmapSource(WPF)......因为这是一个常见问题/题。
This takes three steps:
这需要三个步骤:
- Use an image converter in your binding.
- Create the converter.
- Declare the converter in your resources.
在绑定中使用图像转换器。
创建转换器。
在您的资源中声明转换器。
Here is how you would use an image converter in your binding:
以下是如何在绑定中使用图像转换器:
<Setter
Property="MenuItem.Icon"
Value="{Binding Path=Icon, Converter={StaticResource imageConverter}}"
/>
And, here is the code for the converter (put it into a file called ImageConverter.cs) and add it to your project:
并且,这是转换器的代码(将其放入名为ImageConverter.cs的文件中)并将其添加到您的项目中:
[ValueConversion(typeof(Image), typeof(string))]
public class ImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
BitmapSource bitmapSource;
IntPtr bitmap = ((Bitmap)value).GetHbitmap();
try
{
bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(bitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
finally
{
DeleteObject(bitmap);
}
return bitmapSource;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
[DllImport("gdi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
static extern int DeleteObject(IntPtr o);
}
Here is how you declare it in your resources section (note the local namespace that you will have to add):
以下是在资源部分中声明它的方法(请注意您必须添加的本地命名空间):
<Window
x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
>
<Window.Resources>
<local:ImageConverter x:Key="imageConverter"/>
</Window.Resources>
<!-- some xaml snipped for clarity -->
</Window>
And that's it!
就是这样!
Update
After doing a quick search for similar questions, I noticed that Lars Truijens pointed out here that the previous converter implementation leaks. I have updated the converter code above ... so that it doesn't leak.
在快速搜索类似问题后,我注意到Lars Truijens在此指出前一个转换器实现泄漏。我已经更新了上面的转换器代码......这样它就不会泄漏。
For more information on the cause of the leak, see the remarks section on this MSDN link.
有关泄漏原因的详细信息,请参阅此MSDN链接上的备注部分。
#3
1
WPF's menuitems are somewhat weird in that they don't work with ImageSource objects like the rest of the WPF framework.
WPF的menuitems有些奇怪,因为它们不能像其他WPF框架一样使用ImageSource对象。
The easiest way, that will cause you the least amount of headache is to simply have a property in your viewmodel that returns a full Image control:
最容易让您头痛的方法是在viewmodel中添加一个返回完整Image控件的属性:
public Image MenuIcon
{
get
{
return new Image()
{
Source = CreateImageSource("myImage.png")
};
}
}
And then in your <Style>
for menu items (which you can set in ItemContainerStyle for example) you simply bind the menu item's Icon
property to the MenuIcon
property in your viewmodel:
然后在
<Setter Property="Icon" Value="{Binding MenuIcon}" />
One could argue that this breaks the spirit of MVVM, but at some point you just have to be pragmatic and move on to more interesting problems.
有人可能会说这打破了MVVM的精神,但在某些时候你必须务实并转向更有趣的问题。
#4
0
Here's how I made a ViewModel for a menu item: AbstractMenuItem. Pay particular attention to the Icon region:
以下是我为菜单项创建ViewModel的方法:AbstractMenuItem。特别注意Icon区域:
#region " Icon "
/// <summary>
/// Optional icon that can be displayed in the menu item.
/// </summary>
public object Icon
{
get
{
if (IconFull != null)
{
System.Windows.Controls.Image img = new System.Windows.Controls.Image();
if (EnableCondition.Condition)
{
img.Source = IconFull;
}
else
{
img.Source = IconGray;
}
return img;
}
else
{
return null;
}
}
}
private BitmapSource IconFull
{
get
{
return m_IconFull;
}
set
{
if (m_IconFull != value)
{
m_IconFull = value;
if (m_IconFull != null)
{
IconGray = ConvertFullToGray(m_IconFull);
}
else
{
IconGray = null;
}
NotifyPropertyChanged(m_IconArgs);
}
}
}
private BitmapSource m_IconFull = null;
static readonly PropertyChangedEventArgs m_IconArgs =
NotifyPropertyChangedHelper.CreateArgs<AbstractMenuItem>(o => o.Icon);
private BitmapSource IconGray { get; set; }
private BitmapSource ConvertFullToGray(BitmapSource full)
{
FormatConvertedBitmap gray = new FormatConvertedBitmap();
gray.BeginInit();
gray.Source = full;
gray.DestinationFormat = PixelFormats.Gray32Float;
gray.EndInit();
return gray;
}
/// <summary>
/// This is a helper function so you can assign the Icon directly
/// from a Bitmap, such as one from a resources file.
/// </summary>
/// <param name="value"></param>
protected void SetIconFromBitmap(System.Drawing.Bitmap value)
{
BitmapSource b = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
value.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
IconFull = b;
}
#endregion
You just derive from this class and in the constructor you call SetIconFromBitmap and pass in a picture from your resx file.
您只需从此类派生,并在构造函数中调用SetIconFromBitmap并从resx文件传入图片。
Here's how I bound to those IMenuItems in the Workbench Window:
这是我在Workbench窗口中绑定到那些IMenuItems的方式:
<Menu DockPanel.Dock="Top" ItemsSource="{Binding Path=(local:Workbench.MainMenu)}">
<Menu.ItemContainerStyle>
<Style>
<Setter Property="MenuItem.Header" Value="{Binding Path=(contracts:IMenuItem.Header)}"/>
<Setter Property="MenuItem.ItemsSource" Value="{Binding Path=(contracts:IMenuItem.Items)}"/>
<Setter Property="MenuItem.Icon" Value="{Binding Path=(contracts:IMenuItem.Icon)}"/>
<Setter Property="MenuItem.IsCheckable" Value="{Binding Path=(contracts:IMenuItem.IsCheckable)}"/>
<Setter Property="MenuItem.IsChecked" Value="{Binding Path=(contracts:IMenuItem.IsChecked)}"/>
<Setter Property="MenuItem.Command" Value="{Binding}"/>
<Setter Property="MenuItem.Visibility" Value="{Binding Path=(contracts:IControl.Visible),
Converter={StaticResource BooleanToVisibilityConverter}}"/>
<Setter Property="MenuItem.ToolTip" Value="{Binding Path=(contracts:IControl.ToolTip)}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(contracts:IMenuItem.IsSeparator)}" Value="true">
<Setter Property="MenuItem.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Separator Style="{DynamicResource {x:Static MenuItem.SeparatorStyleKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Menu.ItemContainerStyle>
</Menu>
#5
0
For posterity: I've come up with this:
后人:我想出了这个:
<Menu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Icon" Value="{Binding IconUrl, Converter={ns:UrlToImageConverter Width=16, Height=16}}"/>
</Style>
</Menu.ItemContainerStyle>
The converter is a combination of MarkupExtension
and a IValueConverter
, so you can specify it inline without having to make it a static resource.
转换器是MarkupExtension和IValueConverter的组合,因此您可以将其指定为内联而无需使其成为静态资源。
It uses the System.Windows.Media.ImageSourceConverter
to convert an uri to an ImageSource
and then creates an Image
control with that source. As bonus it uses the serviceProvider
parameter as supplied to ProvideValue
so it can resolve relative image urls as WPF would do it.
它使用System.Windows.Media.ImageSourceConverter将uri转换为ImageSource,然后使用该源创建一个Image控件。作为奖励,它使用提供给ProvideValue的serviceProvider参数,因此它可以解析相对图像URL,因为WPF会这样做。
[ValueConversion(typeof(string), typeof(Image))]
[ValueConversion(typeof(Uri), typeof(Image))]
public class UrlToImageConverter : MarkupExtension, IValueConverter
{
public int? MaxWidth { get; set; }
public int? MaxHeight { get; set; }
public int? MinWidth { get; set; }
public int? MinHeight { get; set; }
public Stretch? Stretch { get; set; }
public StretchDirection? StretchDirection { get; set; }
private static readonly ImageSourceConverter _converter = new System.Windows.Media.ImageSourceConverter();
private readonly IServiceProvider _serviceProvider;
public UrlToImageConverter()
{
_serviceProvider = new ServiceContainer();
}
/// <summary> </summary>
private UrlToImageConverter(UrlToImageConverter provider, IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider ?? new ServiceContainer();
MaxWidth = provider.MaxWidth;
MaxHeight = provider.MaxHeight;
MinWidth = provider.MinWidth;
MinHeight = provider.MinHeight;
Stretch = provider.Stretch;
StretchDirection = provider.StretchDirection;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return null;
var context = GetTypeDescriptorContext();
bool canConvert;
if (context == null)
canConvert = _converter.CanConvertFrom(value.GetType());
else
canConvert = _converter.CanConvertFrom(context, value.GetType());
if (canConvert)
{
if (context == null)
value = _converter.ConvertFrom(value);
else
value = _converter.ConvertFrom(context, CultureInfo.CurrentCulture, value);
if (value is ImageSource source)
{
var img = new Image { Source = source };
if (MaxWidth != null) img.MaxWidth = MaxWidth.Value;
if (MaxHeight != null) img.MaxHeight = MaxHeight.Value;
if (MinWidth != null) img.MinWidth = MinWidth.Value;
if (MinHeight != null) img.MinHeight = MinHeight.Value;
img.Stretch = Stretch ?? System.Windows.Media.Stretch.Uniform;
img.StretchDirection = StretchDirection ?? System.Windows.Controls.StretchDirection.Both;
return img;
}
}
return null;
}
private ITypeDescriptorContext GetTypeDescriptorContext()
{
if (_serviceProvider is ITypeDescriptorContext context)
return context;
else
return (ITypeDescriptorContext)_serviceProvider?.GetService(typeof(ITypeDescriptorContext));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return new UrlToImageConverter(this, serviceProvider);
}
}
#1
5
WPF works with ImageSource
s, not System.Drawing
classes. You'll need to bind to an ImageSource
. You could use a converter to convert your Bitmap
to an ImageSource
, or you could ditch the resources and do things differently.
WPF适用于ImageSources,而不适用于System.Drawing类。您需要绑定到ImageSource。您可以使用转换器将Bitmap转换为ImageSource,或者您可以放弃资源并以不同方式执行操作。
#2
9
Kent (of course) has the right answer. But I thought I would go ahead and post the code for the converter that converts from the System.Drawing.Bitmap (Windows Forms) to a System.Windows.Windows.Media.BitmapSource (WPF) ... as this is a common problem/question.
肯特(当然)有正确的答案。但我想我会继续发布转换器的代码,该转换器从System.Drawing.Bitmap(Windows窗体)转换为System.Windows.Windows.Media.BitmapSource(WPF)......因为这是一个常见问题/题。
This takes three steps:
这需要三个步骤:
- Use an image converter in your binding.
- Create the converter.
- Declare the converter in your resources.
在绑定中使用图像转换器。
创建转换器。
在您的资源中声明转换器。
Here is how you would use an image converter in your binding:
以下是如何在绑定中使用图像转换器:
<Setter
Property="MenuItem.Icon"
Value="{Binding Path=Icon, Converter={StaticResource imageConverter}}"
/>
And, here is the code for the converter (put it into a file called ImageConverter.cs) and add it to your project:
并且,这是转换器的代码(将其放入名为ImageConverter.cs的文件中)并将其添加到您的项目中:
[ValueConversion(typeof(Image), typeof(string))]
public class ImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
BitmapSource bitmapSource;
IntPtr bitmap = ((Bitmap)value).GetHbitmap();
try
{
bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(bitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
finally
{
DeleteObject(bitmap);
}
return bitmapSource;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
[DllImport("gdi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
static extern int DeleteObject(IntPtr o);
}
Here is how you declare it in your resources section (note the local namespace that you will have to add):
以下是在资源部分中声明它的方法(请注意您必须添加的本地命名空间):
<Window
x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
>
<Window.Resources>
<local:ImageConverter x:Key="imageConverter"/>
</Window.Resources>
<!-- some xaml snipped for clarity -->
</Window>
And that's it!
就是这样!
Update
After doing a quick search for similar questions, I noticed that Lars Truijens pointed out here that the previous converter implementation leaks. I have updated the converter code above ... so that it doesn't leak.
在快速搜索类似问题后,我注意到Lars Truijens在此指出前一个转换器实现泄漏。我已经更新了上面的转换器代码......这样它就不会泄漏。
For more information on the cause of the leak, see the remarks section on this MSDN link.
有关泄漏原因的详细信息,请参阅此MSDN链接上的备注部分。
#3
1
WPF's menuitems are somewhat weird in that they don't work with ImageSource objects like the rest of the WPF framework.
WPF的menuitems有些奇怪,因为它们不能像其他WPF框架一样使用ImageSource对象。
The easiest way, that will cause you the least amount of headache is to simply have a property in your viewmodel that returns a full Image control:
最容易让您头痛的方法是在viewmodel中添加一个返回完整Image控件的属性:
public Image MenuIcon
{
get
{
return new Image()
{
Source = CreateImageSource("myImage.png")
};
}
}
And then in your <Style>
for menu items (which you can set in ItemContainerStyle for example) you simply bind the menu item's Icon
property to the MenuIcon
property in your viewmodel:
然后在
<Setter Property="Icon" Value="{Binding MenuIcon}" />
One could argue that this breaks the spirit of MVVM, but at some point you just have to be pragmatic and move on to more interesting problems.
有人可能会说这打破了MVVM的精神,但在某些时候你必须务实并转向更有趣的问题。
#4
0
Here's how I made a ViewModel for a menu item: AbstractMenuItem. Pay particular attention to the Icon region:
以下是我为菜单项创建ViewModel的方法:AbstractMenuItem。特别注意Icon区域:
#region " Icon "
/// <summary>
/// Optional icon that can be displayed in the menu item.
/// </summary>
public object Icon
{
get
{
if (IconFull != null)
{
System.Windows.Controls.Image img = new System.Windows.Controls.Image();
if (EnableCondition.Condition)
{
img.Source = IconFull;
}
else
{
img.Source = IconGray;
}
return img;
}
else
{
return null;
}
}
}
private BitmapSource IconFull
{
get
{
return m_IconFull;
}
set
{
if (m_IconFull != value)
{
m_IconFull = value;
if (m_IconFull != null)
{
IconGray = ConvertFullToGray(m_IconFull);
}
else
{
IconGray = null;
}
NotifyPropertyChanged(m_IconArgs);
}
}
}
private BitmapSource m_IconFull = null;
static readonly PropertyChangedEventArgs m_IconArgs =
NotifyPropertyChangedHelper.CreateArgs<AbstractMenuItem>(o => o.Icon);
private BitmapSource IconGray { get; set; }
private BitmapSource ConvertFullToGray(BitmapSource full)
{
FormatConvertedBitmap gray = new FormatConvertedBitmap();
gray.BeginInit();
gray.Source = full;
gray.DestinationFormat = PixelFormats.Gray32Float;
gray.EndInit();
return gray;
}
/// <summary>
/// This is a helper function so you can assign the Icon directly
/// from a Bitmap, such as one from a resources file.
/// </summary>
/// <param name="value"></param>
protected void SetIconFromBitmap(System.Drawing.Bitmap value)
{
BitmapSource b = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
value.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
IconFull = b;
}
#endregion
You just derive from this class and in the constructor you call SetIconFromBitmap and pass in a picture from your resx file.
您只需从此类派生,并在构造函数中调用SetIconFromBitmap并从resx文件传入图片。
Here's how I bound to those IMenuItems in the Workbench Window:
这是我在Workbench窗口中绑定到那些IMenuItems的方式:
<Menu DockPanel.Dock="Top" ItemsSource="{Binding Path=(local:Workbench.MainMenu)}">
<Menu.ItemContainerStyle>
<Style>
<Setter Property="MenuItem.Header" Value="{Binding Path=(contracts:IMenuItem.Header)}"/>
<Setter Property="MenuItem.ItemsSource" Value="{Binding Path=(contracts:IMenuItem.Items)}"/>
<Setter Property="MenuItem.Icon" Value="{Binding Path=(contracts:IMenuItem.Icon)}"/>
<Setter Property="MenuItem.IsCheckable" Value="{Binding Path=(contracts:IMenuItem.IsCheckable)}"/>
<Setter Property="MenuItem.IsChecked" Value="{Binding Path=(contracts:IMenuItem.IsChecked)}"/>
<Setter Property="MenuItem.Command" Value="{Binding}"/>
<Setter Property="MenuItem.Visibility" Value="{Binding Path=(contracts:IControl.Visible),
Converter={StaticResource BooleanToVisibilityConverter}}"/>
<Setter Property="MenuItem.ToolTip" Value="{Binding Path=(contracts:IControl.ToolTip)}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(contracts:IMenuItem.IsSeparator)}" Value="true">
<Setter Property="MenuItem.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Separator Style="{DynamicResource {x:Static MenuItem.SeparatorStyleKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Menu.ItemContainerStyle>
</Menu>
#5
0
For posterity: I've come up with this:
后人:我想出了这个:
<Menu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Icon" Value="{Binding IconUrl, Converter={ns:UrlToImageConverter Width=16, Height=16}}"/>
</Style>
</Menu.ItemContainerStyle>
The converter is a combination of MarkupExtension
and a IValueConverter
, so you can specify it inline without having to make it a static resource.
转换器是MarkupExtension和IValueConverter的组合,因此您可以将其指定为内联而无需使其成为静态资源。
It uses the System.Windows.Media.ImageSourceConverter
to convert an uri to an ImageSource
and then creates an Image
control with that source. As bonus it uses the serviceProvider
parameter as supplied to ProvideValue
so it can resolve relative image urls as WPF would do it.
它使用System.Windows.Media.ImageSourceConverter将uri转换为ImageSource,然后使用该源创建一个Image控件。作为奖励,它使用提供给ProvideValue的serviceProvider参数,因此它可以解析相对图像URL,因为WPF会这样做。
[ValueConversion(typeof(string), typeof(Image))]
[ValueConversion(typeof(Uri), typeof(Image))]
public class UrlToImageConverter : MarkupExtension, IValueConverter
{
public int? MaxWidth { get; set; }
public int? MaxHeight { get; set; }
public int? MinWidth { get; set; }
public int? MinHeight { get; set; }
public Stretch? Stretch { get; set; }
public StretchDirection? StretchDirection { get; set; }
private static readonly ImageSourceConverter _converter = new System.Windows.Media.ImageSourceConverter();
private readonly IServiceProvider _serviceProvider;
public UrlToImageConverter()
{
_serviceProvider = new ServiceContainer();
}
/// <summary> </summary>
private UrlToImageConverter(UrlToImageConverter provider, IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider ?? new ServiceContainer();
MaxWidth = provider.MaxWidth;
MaxHeight = provider.MaxHeight;
MinWidth = provider.MinWidth;
MinHeight = provider.MinHeight;
Stretch = provider.Stretch;
StretchDirection = provider.StretchDirection;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return null;
var context = GetTypeDescriptorContext();
bool canConvert;
if (context == null)
canConvert = _converter.CanConvertFrom(value.GetType());
else
canConvert = _converter.CanConvertFrom(context, value.GetType());
if (canConvert)
{
if (context == null)
value = _converter.ConvertFrom(value);
else
value = _converter.ConvertFrom(context, CultureInfo.CurrentCulture, value);
if (value is ImageSource source)
{
var img = new Image { Source = source };
if (MaxWidth != null) img.MaxWidth = MaxWidth.Value;
if (MaxHeight != null) img.MaxHeight = MaxHeight.Value;
if (MinWidth != null) img.MinWidth = MinWidth.Value;
if (MinHeight != null) img.MinHeight = MinHeight.Value;
img.Stretch = Stretch ?? System.Windows.Media.Stretch.Uniform;
img.StretchDirection = StretchDirection ?? System.Windows.Controls.StretchDirection.Both;
return img;
}
}
return null;
}
private ITypeDescriptorContext GetTypeDescriptorContext()
{
if (_serviceProvider is ITypeDescriptorContext context)
return context;
else
return (ITypeDescriptorContext)_serviceProvider?.GetService(typeof(ITypeDescriptorContext));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return new UrlToImageConverter(this, serviceProvider);
}
}