Showing Bitmap Images in WPF via C# - wpf

What I am trying to do is so simple but I am having a hard time making it work. I saw some posts along the same lines but I still have questions.
I have a MenuItem object called mnuA. All I want is set the icon property programatically in C#. I have tried the following
a) mnuA.Icon = new BitmapImage{UriSource = new Uri(#"c:\icons\A.png")};
Results: Instead of showing the actual icon, I get the class name (System.Windows.Media.Imaging.BitmapImage)
b) mnuA.Icon = new BitmapImage(new Uri(#"c:\icons\A.png"));
Results: Instead of showing the actual icon, I get the path of the image (file:///c:/icons/A.png)
What am I doing wrong? Do I really need a converter class for something simple like this?

Try this:
Image img = new Image();
img.Source = new BitmapImage(new Uri(#"c:\icons\A.png"));
mnuA.Icon = img;

Might be a long shot, but try something like:
Uri u = new Uri(...); mnuA.Icon = new
BitmapImage(u);
What it seems its happening is that your icon is getting converted to a string.

Related

How to remove/disable the print button from the DocumentViewer in code (when on its own thread)?

I am running the following code in a background thread as an STA apartment to provide a Print Preview in a document viewer:
// Print Preview
public static void PrintPreview(FixedDocument fixeddocument)
{
MemoryStream ms = new MemoryStream();
using (Package p = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite))
{
Uri u = new Uri("pack://TemporaryPackageUri.xps");
PackageStore.AddPackage(u, p);
XpsDocument doc = new XpsDocument(p, CompressionOption.Maximum, u.AbsoluteUri);
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
writer.Write(fixeddocument.DocumentPaginator);
var previewWindow = new Window();
var docViewer = new DocumentViewer();
previewWindow.Content = docViewer;
THIS FAILS ---> docViewer.CommandBindings.Remove(???Print Button???);
FixedDocumentSequence fixedDocumentSequence = doc.GetFixedDocumentSequence();
docViewer.Document = fixedDocumentSequence as IDocumentPaginatorSource;
previewWindow.ShowDialog();
PackageStore.RemovePackage(u);
doc.Close();
}
}
All works well. However, since this is running in its own thread--not the main thread--the print dialogue on the Document Viewer crashes.
In code, how can I remove and/or disable the Print button from the DocumentViewer?? (I have read everything I could find in Google, and it all is in XAML, not very helpful).
Any help is much appreciated. TIA
Update#1: The only way I can see to do this, is to drop the Print Button from the control template and use a custom Document Viewer. A workable style is given at Document Viewer Style.
It still would be nice if I could simply remove the button from the system Document viewer?
Using the method from this answer, you can alter the visibility of the PrintButton programmatically like this. Let's say I put the method in a class called UIElementHelper:
var button = UIElementHelper.FindChild<Button>(docViewer, "PrintButton");
button.Visibility = Visibility.Collapsed;

Printing RTF with headers and footers - FlowDocument or something else?

I've been looking at importing an RTF into a flowdocument, obstinately for the purposes of unattended printing; after a lot of poking, using a FlowDocument seemed to be the right approach. I've got the RTF to generally work, however footers disappear when loading the RTF into a FlowDocument.
The RTF was generated in Word, and when loaded into Wordpad, the footers are visible, so I can only assume I'm loading the document wrong, or it's an issue with the default paginator, or possibly both.
This is what I have so far, which loads the file and does the printing:
[STAThread]
public static int Main(string[] args)
{
var documentPath = #"C:\temp\Example.rtf";
var fileStream = File.Open(documentPath, FileMode.Open, FileAccess.Read, FileShare.Read);
// Load the RTF into the flow document
var flowDocument = new FlowDocument();
TextRange textRange = new TextRange(flowDocument.ContentStart, flowDocument.ContentEnd);
textRange.Load(fileStream, DataFormats.Rtf);
flowDocument.ColumnWidth = double.PositiveInfinity;
var t = new Thickness(72);
flowDocument.PagePadding = t; // Page margin
// Get printer
var queue = LocalPrintServer.GetDefaultPrintQueue();
var capa = queue.GetPrintCapabilities();
// Configure paginator
var paginator = ((IDocumentPaginatorSource)flowDocument).DocumentPaginator;
paginator.PageSize = new Size(capa.OrientedPageMediaWidth.Value, capa.OrientedPageMediaHeight.Value);
// ...and print.
var writer = System.Printing.PrintQueue.CreateXpsDocumentWriter(queue);
writer.Write(paginator);
return 0;
}
...beyond that, I'm at a loss. It's not clear whether the footers simply haven't loaded (and thus aren't part of the FlowDocument) - I suspect this is the case as we're loading into a TextRange that marks the start and end of the main FlowDocument content; but I'm also suspecting I might need a custom paginator as well.
Are there any pointers to the docs I'm missing - a google search for "RTF footer import flowdocument paginator" (and similar) has (so far) revealed no pertinent results. The closest I've so far found is this SO question, but this doesn't cover fetching the header/footer from an RTF file.
Take a look at this MSDN blogpost they are doing almost the same you are doing. With a custom DocumentPaginator to scale the the original pages. I think this should do the trick. I also used it a long time ago and headers and footers were no problem.
To provide the header and footer property during printing, we usually handle the PrintPage event and provide these features in this event handler. Here is a sample for your reference. Although this sample is a printer class for DataGridView, you can take the logic of add the header and footer features.
· http://www.codeproject.com/KB/cs/DGVPrinter.aspx
If you are using the WebBrowser to print the HTML, you can custom the header and footer like mentioned in the following article.
· http://www.codeproject.com/KB/miscctrl/tips.aspx#tip3.8.2

setting URL as mediaElement source

I keep getting an "object reference not set to an instance of an object" and i have absolutely no idea why!
MediaElement1.Source = New URI(trackstream(0), UriKind.Absolute)
If i mouseover to check everything it seems fine, that variable position contains a direct link to an mp3, It even says if i mouseover it that the Source has been set to that URL but then i get this error.
i am just trying to set url as the first in a list that i have downloaded from a textfile previously, then put into that array. I have tried changing the urlkind and omitting it.
This works:
public MainWindow()
{
string[] trackstream = new string[] { #"C:\Users\Public\Music\Sample Music\sound.wma" };
InitializeComponent();
media.Source = new Uri(trackstream[0], UriKind.Absolute);
}

Silverlight InlineCollection.Add(InlineUIContainer) missing?

I'm having difficulty adding the inline of specific type InlineUIContainer into the InlineCollection (Content property) of a TextBlock. It appears the .Add() method of InlineCollection doesn't accept this type, however you can clearly set it through XAML without explicitly marking the content as a InlineContainer, as demonstrated in many examples:
http://msdn.microsoft.com/en-us/library/system.windows.documents.inlineuicontainer.aspx
Is it possible to programatically add one of these as in the following?
Target.Inlines.Add(new Run() { Text = "Test" });
Target.Inlines.Add(new InlineUIContainer() {
Child = new Image() { Source = new BitmapImage(new Uri("http://example.com/someimage.jpg")) } });
Target.Inlines.Add(new Run() { Text = "TestEnd" });
I have a feeling what's going on is that Silverlight is using a value converter to create the runs when specified in XAML as in the example which doesn't use InlineContainer, but I'm not sure where to look to find out.
The specific error I'm getting is as follows:
Cannot add value of type 'System.Windows.Documents.InlineUIContainer' to a 'InlineCollection' in a 'System.Windows.Controls.TextBlock'.
As pointed out by Jedidja, we need to use RichTextBox to do this in Silverlight.
You can't Add() Runs directly, but you can add Spans containing Runs.
Interestingly, you can also do this:
textBlock.Inlines.Clear();
textBlock.Inlines.Add(new Span());
textBlock.Inlines[0] = new Run();
Not that it's a good idea to hack around what the framework is actively trying to prevent you from doing.
P.S. If you can't figure out what XAML is doing, inspect the visual tree.

Is there a way to display a image in WPF stored in memory?

What I got is something like a screenshot making application. (managed to serialize, thank god!!!) When a button is clicked a screenshot is taken by accessing a handling classe's method. now the tricky part is that the class has another method for operating with the above said result, in such a manner than when the respective handling method is called, a window is created(shown) and the bitmap image should go into a display container in that window. The problem is that so far, I've noticed that in WPF the image control's source cannot be attribuited to a variable which stores the image. How can i display the image stored in that variable without having to save it first,get uri,etc. ?
You need to create an image from a memory stream, this has been well documented by many people. Here are two links that may get you started:
http://forums.silverlight.net/forums/p/44637/166282.aspx
http://www.wpftutorial.net/Images.html
thanks for the links slugster. Here's how I did it:
MemoryStream ms = new MemoryStream();
sBmp = gBmp; //note: gBmp is a variable that stores the captured image and passes it on to the method that uses sBMP as a distribuitor of the variable holding the captured image data
//variable that holds image
sBmp.Save(ms,ImageFormat.Bmp);
//my buffer byte
byte[] buffer = ms.GetBuffer();
//Create new MemoryStream that has the contents of buffer
MemoryStream bufferPasser = new MemoryStream(buffer);
//Creates a window with parents classthatholdsthismethod and null
Edit childEdit = new Edit(this, null);
childEdit.Show();
//I create a new BitmapImage to work with
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = bufferPasser;
bitmap.EndInit();
//I set the source of the image control type as the new BitmapImage created earlier.
childEdit.imgImageCanvas.Source = bitmap;
childEdit.Activate();
I've basically combined what I had found on those pages with some info I found on how to pass on a bmp to a memstream. I got this to work 100% :)

Resources