Display WinForm Image in WPF application - wpf

I have a dll with quite a bit of System.Drawing.Image resources that I have wrapped into static properties so I can update them dynamically.
I would like to use the images through xaml in a WPF application, but the only way I can figure is to do it through the code behind manually.
Is there a way to do the winform to wpf image convertion on a static property in xaml?

You could bind to your images directly, using a converter. Here is an example in a window:
<Window.Resources>
<WinForms2WPFImageConverter x:Key="WF2WPFDrawingConverter" />
</Window.Resources>
...
This SO question has a drawing converter, which I adapted here as a ValueConverter.
public class WinForms2WPFImageConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
System.Drawing.Image i = (System.Drawing.Image) value;
using (MemoryStream drawingStream = new MemoryStream())
{
i.Save(drawingStream);
i.Seek(0, SeekOrigin.Begin);
return System.Windows.Media.Imaging.BitmapFrame.Create(drawingStream);
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new InvalidOperationException();
}
}
Of course, you need to account for namespaces in the declaration of the resource.
I advise not using static properties, in order to leverage INotifyPropertyChanged (or dependency properties), so that the display automatically changes when the properties point to other images.
(note: this was typed, not copied from VS, so there may be a syntax error somewhere.)

You could bind to your images using a Method in WPF. Here is an example in a link
http://microsoftdotnetsolutions.blogspot.com/2016/07/convert-winforms-image-to-wpf.html

Related

How do I bind a DataGrid Width to a converter?

I want to include the size of the VerticalScrollbar when i define the width of a DataGrid.
So far i wrote a Converter:
[ValueConversion(typeof(double), typeof(double))]
public class VerticalScrollbarConverter : IValueConverter
{
#region IValueConverter Member
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is double)
return (double)value + SystemParameters.VerticalScrollBarWidth;
else
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
I included my converter in the xaml namespace with:
xmlns:Core="clr-namespace:Core;assembly=SMS_Core"
And I defined the converter as a (window) resource:
<Window.Resources>
<Core:VerticalScrollbarConverter x:Key="VerticalScrollbarConverter"/>
</Window.Resources>
Since all of my DataGrid.Columns have a fixed Value I know the value that i need to pass.
How do I tell my GridView Width property in xaml to use the converter?
I know that my question is pretty basic. As you can tell I am very new to WPF.
Thanks in advance for every hint. If you need some more info or context just ask away.
The comment from sa_ddam213 didn't exactly solve the problem. But it sure did push me into the right direction.
To pass the value automatically I had to do the following:
I created a property in the window class called TotalColumnWidth. Returning this:
myDataGrid.Columns.Sum(c => c.ActualWidth);
The xaml is the following:
Width="{Binding ElementName=_Root, Path=TotalColumnWidth, Converter={StaticResource ResourceKey=VerticalScrollbarConverter}}"
Using the converter mentioned above.

Can I bind a textblock's content to only part of a string in an observable collection?

I'm relatively new to WPF so apologies if there is an obvious or simple answer to this that I am not seeing.
I have an ObservableCollection of items with several different sized images for each.
The relative path for each image is in string format, with image files stored in different subfolders.
The image paths are in the format:
imagepath = #"subfolder/subfolder/filename.png"
I would like to be able to bind to a textblock but show only the filename below each image without changing the image path. Is this possible? I gather it would require a converter of some sort, but I have been struggling with it as I cannot find a reasonable way of showing only part of a string.
Thanks for your help.
Edit
To clarify, my 'value' is non-static, referencing items in an observable collection eg.
ObservableCollection<Icon> items = new ObservableCollection<Item>();
items.Add(new Item{imagename = "someimagename",
imagepath= "somefolder/somesubfolder/somefilename.png"}) etc...
I'm only starting to get to grips with 'getting' values from my collection. Any help with filling in the 'value.Tostring()' part to get dynamic values for item.imagepath would be really appreciated so I can get this working.
I've currently been trying along these lines:
class getFilenameFromPathConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{ Item item = value as Item;
PropertyInfo info = value.GetType().GetProperty("imagepath");
string filename = info.GetValue(item, null).ToString();
return System.IO.Path.GetFileNameWithoutExtension(filename); }
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
But I'm getting an Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
Thanks
XAML as specified by fatty.
Your converter should look like:
class getFilenameFromPathConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Path.GetFileName(value.ToString());
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
You will need to enlist the help of a converter to get this value.
Create a class that implements IValueConverter, and in the Convert method return the part of the string that you want to display.
In your TextBlock, you bind to the property like {Binding Path=imagepath, Converter={StaticResource getFilenameFromPathConverter}}

Silverlight Custom Button content

What would be a good way to have the text (content) of buttons per-client configurable in a SL 4 app? I'm still pretty novice w/ SL so this may seem trivial.
The issue isn't new. The system currently has a static XAML attribute for ButtonA's content as "Do Stuff" (Content="DoStuff"). Now one client wants that to read "Do Things". This will continue to crop up on occasion in arbitrary places across the system.
I have a dictionary available that will contain the custom text, but would LIKE (if possible) to be able to have a default value and only override if there is a dictionary entry.
Conceptually, it would be nice to be able to have:
<Button Content="Do Stuff" OverrideContentKey="ButtonAOverrideContent" />
where if the dictionary has a key of ButtonAOverrideContent, it will override it, but otherwise "Do Stuff" will show.
Is there a way to perhaps write a converter and make some entries in App.xaml that would then allow all buttons to conditionally override the content? What I've seen of converters looks like there's not a smooth way to pass information about the control (e.g. the override key) to them.
You can use a ConverterParameter property of a Binding to pass your override content key to a converter.
public class ReplaceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string key = (string)parameter;
var someDictionary = GetYourReplacementDictionary();
if (someDictionary.ContainsKey(key))
{
return someDictionary[key];
}
else
{
return value;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
In your App.Xaml resources:-
<local:ReplaceConverter x:Key="replacer" />
Then on a button:-
<Button Content="{Binding Source='Do Stuff', ConverterParameter=ButtonAOverrideContent, Converter={StaticResource replacer}}" />

Using Resourse.resx in WPF application to set color

I´m trying to make an application that has to be able to easily change a dll file which could change colors in the application.
I´m trying to use resource manager to do this but am having problems with setting color values so that the styles for views can easily accept it.
We know that(in this case) the background of a button takes in SolidColorBrush, and while
Value="Black" works,
Value={x:Static res:AppResources.Btn_Background}
which gives the string Black does not (current theory being that converters make the former work but not the latter).
This is all being done in wpf & mvvm.
Have you guys an idea about how this could be done.
Greetings
You could use a Binding:
Background="{Binding Source={x:Static res:AppResources.Btn_Background}}"
This will cause the CoerceValue to fire for the DependencyProperty controlling the background.
#Snowbear mentioned it may be a Color rather than a String, in which case you would need to provide a trivial IValueConverter.
public class ColorConverter: IValueConverter
{
#region IValueConverter Members
private Dictionary<Color, Brush> brushes = new Dictionary<Color, Brush>();
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
Brush brush;
var color = (Color)value;
if (!brushes.TryGetValue(color, out brush))
{
brushes[color] = brush = new SolidColorBrush(color);
brush.Freeze();
}
return brush;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
Your specific issue is that you are bypassing the default string to Brush conversion and would need to handle that manually.
As sixlettervariables states, you'd can use a Binding if your source is a string, but that is probably overkill. At a minimum, you'd want to set Mode=OneTime on the Binding.
You can also create a custom MarkupExtension that performs the conversion.
Your conversion, whether it be through a custom IValueConverter or MarkupExtension, can leverage the BrushConverter class. So things like "Black" or "#000" will work as they do when defining the color in XAML like your first example.
EDIT:
Actually a markup extension that derives from StaticExtension, makes this easier:
public class BrushStaticExtension : StaticExtension {
private static BrushConverter converter = new BrushConverter();
public BrushStaticExtension() { }
public BrushStaticExtension(string member) : base (member) { }
public override object ProvideValue(IServiceProvider serviceProvider) {
return converter.ConvertFrom(base.ProvideValue(serviceProvider));
}
}
If you specify a string then XAML parser uses a converter from string which automatically creates a SolidColorBrush. As far as I understand at the moment Btn_Background resource is Color but it should be a SolidColorBrush instead.

How can I easily add a WPF Converter item template to Visual Studio?

I find myself creating Converters often and would like to be able to:
right-click on my Converters folder
Add New Item...
choose Converter Item Template
I found these instructions but I can imagine that there are templates for standard files like WPF Converters already available somewhere, does anyone know of any?
The following file would be created:
[ValueConversion(typeof(string), typeof(string))]
class SaveStatusToSaveStatusMessageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
}
the nerd+art snippets have a snippet called nerd_vc which generates a valueconverter for you. You can customize it to your liking, good luck!
http://www.blendables.com/files/folders/nerd_43_art/entry387.aspx
oh. sorry, i´m tired. what you want is not snippets.... I´ll leave the post here tough :)

Resources