Powershell - Displaying an XPS document in Document Viewer using WPF - wpf

I am trying to load a docx file in documentviewer using WPF (PowerShell). I figured that I can't do it for a docx file, so i am converting the docx file to XPS first. But I am not sure how to load the XPS document into DocumentViewer.
To load the document I probably need something like this, but I get an error:
New-Object : A constructor was not found. Cannot find an appropriate constructor for type System.Windows.Documents.IDocumentPaginatorSource.
XAML...
<DocumentViewer Name="docViewer" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
$docViewer = $form.FindName('docViewer')
$docViewer.Document = New-Object System.Windows.Documents.IDocumentPaginatorSource('test.xps')

Got it...
Add-Type -AssemblyName ReachFramework
$docViewer.Document = (New-Object System.Windows.Documents.IDocumentPaginatorSource('test.xps', [System.IO.FileAccess]::Read)).GetFixedDocumentSequence()

Related

Command line equivalent of Visual Studio Add New Page (WPF)

In the WPF first desktop app walkthrough, it uses Visual Studio to explain how to create a new page in a WPF project. I don't use Visual Studio, but I want to make an XAML Page file using the terminal. I can't just create a new file because it has prewritten code for a new Page similar to below:
<Page x:Class="ExpenseIt.ExpenseItHome"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="350" d:DesignWidth="500"
Title="ExpenseIt - Home">
<Grid>
</Grid>
</Page>
I checked the dotnet new documentation and it says nothing about creating a new file. I know I can just have the default contents in a separate file which I can copy and paste but this seems like an inelegant workaround. Is there a command line argument or another way to get the Page WPF Template without Visual Studio?
Edit
To be more specific on what I am looking for, I would like an XAML file and its corresponding .xaml.cs code-behind file with all the using statements. As suggested, I can use XamlReader, which I have tried, but I would preferably like a tool. XamlPadX is outdated and does not have the code-behind that I am looking for.
Edit 2
This is my current code in the console app I am making:
if (args[0].StartsWith("loadpage-"))
{
string className = args[0].Substring("loadpage-".Length);
string xamlOutput = String.Join(
Environment.NewLine,
$"<Page x:Class=\"{className}\"",
"xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"",
"xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"",
"xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"",
"xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"",
"mc:Ignorable=\"d\"",
"d:DesignHeight=\"350\" d:DesignWidth=\"500\"",
$"Title=\"\">",
"<Grid>", "", "</Grid>",
"</Page>");
Console.WriteLine(xamlOutput);
}
else
{
Console.WriteLine("You must enter the argument in the following format: ");
Console.Write("loadpage-CLASSNAME");
}
You could write a console application which uses command line arguments to receive the xaml content via pure text, or text file containing the content of the xaml page.
Load it using XamlReader in Main method of your program.cs:
https://learn.microsoft.com/en-us/dotnet/api/system.windows.markup.xamlreader?view=netcore-3.1

base64 as textbox background?

I have a textbox that has an image linked as it's background.
I'd like to use the base64 version of this image.
I used a very simple windows -form- to ensure the code for enacting the base64 is working correctly, it did.
The part I'm having issue with is linking it in xaml in a wpf style gui.
<TextBox Name="OutTBox" Grid.Column="0" Grid.ColumnSpan="7" Grid.Row="4" Grid.RowSpan="6" Margin="20,5,20,20" Foreground="#FF8CFF8C" IsReadOnly="True" >
<TextBox.Background>
<ImageBrush ImageSource="C:\background.jpg" Stretch="UniformToFill"/>
</TextBox.Background>
</TextBox>
So here is the base64 language I used for the windows form:
Add-Type -AssemblyName PresentationFramework
# Setup the XAML
[xml]$script:xaml = '<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Title="base64 image demo" Height="350" Width="650" Background="Black">
<Grid>
<Image Name="thisistheimage" Stretch="UniformToFill" />
</Grid>
</Window>'
# Create the form and set variables
$script:form = [Windows.Markup.XamlReader]::Load((New-Object System.Xml.XmlNodeReader $xaml))
$xaml.SelectNodes("//*[#Name]") | ForEach-Object { Set-Variable -Name ($_.Name) -Value $form.FindName($_.Name) -Scope Script }
# here's the base64 string
$base64 = "iVBORw0KGgoAAAANSUhEUgAAAEAAAAAuCAIAAAAX9YijAAAABmJLR0QA/wD/AP+gvaeTAAAGCElEQVRogc1Za0xTZxh+TukVWlrB6rjUzrmqM855Q0CGCBOdJiMSZ1zMYvizZaLGchFUrqVFuTjQLWrcjMnc3Mh+LFF3cbDItsyoGOaMJg4cdEZ6k4tlQFvobT8gSMopPd+hEJ9f55zved4+T7/3O985LeX1ekEHrxf79/945swd2tEXBxx/AxSF06e3HT2aPJtuWMBvgFFUVqYVFb3QGQIEAKDTBT+DSMTduvVV5vyMjCU8Hr3VwAEA6HRpxcUbmH9eQGRnx126tEMk4jIhy2TChoZ3s7JW0o4yCgBAq00tKQlahsRExZw5whUr5jMhr1z5kkjETUl5mXaUaQAAFRWppaUpzPm0kEj4YjHfZnMCcLu90dGSqflRUeKhoREAbrdHKhWEhfF8CAQBAGg0G6eTQSjkdnQc1OsPOp1uh8O1c+cygyFXq031x6+sTDMY8vbsecPhcPX3D3d2HmxvP+CTgSwAAI1mY1kZywyhoTyZTNjW1puautDl8sTHx3Z2PouNDffHj4kJN5kGEhMVIyPubdtUN292zZsXxuOFTORQ/jayqaHR/FZe/isLYUbGktZWo1qdcOBAfFzcZ1FRkvv3LSbToJ8AktWro9raeu/d++j8+T91ut9XrYq6du2fiRziGRhFWVlKVdUmFsIrV9q4XM7SpXMpCmvXRjc2dkx0P3duqEwmHD81GAauXm3fvHkRRVEKhRSAj3sAjG5ktCgsTKIoFBb+Qio0Ggeam/+NjAy9e9fsM1Rbm263u7Kzf5h48fp1vck0cPny37299snVWLbQOGpqbrDIACAiQtTX52vIaj1sszmjoz9mQh4FyxYaR0FBUk1NOgshraGQEIp2d/PnHkBIeXk5i4+fiKQkhVjMb2rqZF1h+fJ5LS0fqFQRFEWZTIPx8THV1enNzfqeHltALfs1MBH5+espisrPb2Qnj4+PWbBAumvX8tENTqmUKZXSdetiHj7sCagNwgyMYv16hUQiaGzsYKHV661SqTA9/ct9++I8Hq9K9alEIjh79s7IiDugNtAi9tpAhTK3Uld3My+P5TwsWya/eDGTw6EyMxseP+5nqAq0iJ/piEzk5ibW1W0hkoxDKOQ6nW6r1REZSfCVTTkDnkE8lkPxCNxYIisnT97KyfmZSDKKhQtldrvLbKbfmGkx5Qw4muF1wP4TqQ+1OqG+fgtFkeqg11uJ3GPSXciD4b8ALzgygMLQdwAwdBnCtwDAYwW84L8Oih+wrlqdIBLx9u79fnr7ZGBMaqHhW3iaBWcbDZcbC/l5iAha/Ny51pnOMGkfECQg9i6eaWCtBTzPr4d/iIgacKRE1XdQrWuhAWYwgf9F3J2FgS/GjkWbENVEWvrpqVNPcnIwwz3kbxG7YWsCAE4EADhuwPMfUV1zVdUTtZrMPQegAIrsAc0P19YItxlzyqC0IPIk4MJgA/Oi5uPHDUeOELgAAKguIHI7IrdDdYFA5aeFevYh9G2EvjN26vgD/Z9g/rdMKpqPHTMUFRFYAADI30dMPlx9AMCNgOEEur9iJPTzMCcrBHfB81Phm+C9Aq8LVICHP3buAdjb4bFBoAQApwX2dqZCPy000f0oQqIDujdVVrJzD2CwBc7esWNnLwZbmAqn+0IzDpNOZywuDlY15ghOAJNWaywpIZLId0O0GOI1kO+eiiNeA9HiqThBeKExabXG0lIiiXAR5LvBV4ArhVCF7q/paRGZcDyCqx/SZAzchoPuXWO6AUwVFcayMlJVeDKEKoheA4ARA3hyAM+XGMUdu8KfD/FqAPC6EJ5MH2Bav0qYNBoj2xe6JQ0QxzElD95B23v0Q+zXwHTcBxEsW8hw+LC5ujq4VgAMPwEAgYJAwmYGZsh99yU8SMWDNHR/Q6AiDmAoLJwJ9wAsnwNewAPLOQIVWQt1FRRYamvJfDGG2+Z7wAQEAboOHbKcOEFiaTbAtIWC6z58w9hzG0MIlAj38wcdoxnoys+3fOz7i/F0wOFj4LbvxbAV8AwDAEeAvqs0EloE3si68vIsdXVsbM4KAsxAV26upb5+dqyww1Rr4MV3D+B/cukdthlrA6MAAAAASUVORK5CYII="
# Create a streaming image by streaming the base64 string to a bitmap streamsource
$bitmap = New-Object System.Windows.Media.Imaging.BitmapImage
$bitmap.BeginInit()
$bitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($base64)
$bitmap.EndInit()
# Freeze() prevents memory leaks.
$bitmap.Freeze()
# Set source here. Take note in the XAML as to where the variable name was taken.
$thisistheimage.source = $bitmap
# Show form
$null = $form.ShowDialog()
I'd give you my actual image but it's over 5k lines long. It only takes a fraction of a second to load.
To be clear the base64 will load in the Xaml. I removed the textbox from those grid coords and replaced it with the base64 and it loads fine. just can't seem to work the two together.
Thanks!
I've never used powershell, but it should be as simple as this:
$brush = New-Object System.Windows.Media.ImageBrush
$brush.ImageSource = $bitmap
$thetextbox.Background = $brush

Using Bitmap Class in XAML [duplicate]

I have two .png files added to my resources which I need to access their Uri when doing binding.
My xaml code is as followed:
<Grid>
<Image>
<Image.Source>
<BitmapImage DecodePixelWidth="10" UriSource="{Binding Path=ImagePath}"/>
</Image.Source>
</Image>
</Grid>
and the binding code using ImagePath is:
ImagePath = resultInBinary.StartsWith("1") ? Properties.Resources.LedGreen : Properties.Resources.ledRed;
However
Properties.Resources.LedGreen
returns a Bitmap instead of String containing the Uri of that particular image.
I just want to know how to extract that value without a need to address a path of the image in the directory that it's stored. (Which honestly I am not sure is a right thing to do as I couldn't find any similar situation on the net).
Please let me know if there is even a preferred method to the one I am trying to use if available.
In a WPF application you would usually not store images in Properties/Resources.resx and access them by means of the Properties.Resources class.
Instead you just add the image files to your Visual Studio project as regular files, perhaps in a folder named "Images" or the like. Then you would set their Build Action to Resource, which is done in the Properties window. You get there e.g. by right-clicking the image file and select the Properties menu item. Note that the default value of the Build Action should be Resource for image files anyways.
In order to access these image resources from code you would then use a Pack URI. With the above folder name "Images" and an image file named "LedGreen.png", creating such an URI would look like this:
var uri = new Uri("pack://application:,,,/Images/LedGreen.png");
So you could perhaps declare your property to be of type Uri:
public Uri ImageUri { get; set; } // omitted INotifyPropertyChanged implementation
and set it like this:
ImageUri = resultInBinary.StartsWith("1")
? new Uri("pack://application:,,,/Images/LedGreen.png")
: new Uri("pack://application:,,,/Images/LedRed.png");
Finally your XAML should look like shown below, which relies on built-in type conversion from Uri to ImageSource:
<Grid>
<Image Width="10" Source="{Binding Path=ImageUri}" />
</Grid>
Declare the Properties.Resources.LedGreen property as ImageSource and set it to Uri location rather than the Bitmap object.
Or if you insist of storing it as a bitmap you can get the source by returning Properties.Resources.LedGreen.ImageSource which will be of type ImageSource.
I would prefer the first approach.

RichTextBox removing unknown tags

I'm using richtextbox to show rtf documents created with MS Word
I need to show contents of a document, like the "document schema" in MS Word, which creates schema by
using style tags "\s[number of style]"
I have a problem, which occurs when I load my file in richtextbox. Attempting to get the RTF text only
returns known tags, omitting all the unknown ones.
I use the following code for loading the file
MemoryStream stream = new MemoryStream(Encoding.Default.GetBytes(file));
rtbViewer.Selection.Load(stream,DataFormats.Rtf);
stream.Close();
I've managed to make a contents by regex-searching through the input string file. I get the source file and
get its text in a string (it would be with all its rtf-tags), then I search for style tags and get information about
level and text. Everything is ok as long as the user doesn't change text and then try to save it.
The problem is that when I load file in richtextbox I miss all information about content. When I try to save the
changed document I get Rtf text from richtextbox but it doesn't contain style tags.
MemoryStream ms = new MemoryStream();
rtbViewer.Selection.Save(ms, DataFormats.Rtf);
How can I get all tags from my source file?
This worked for me.
<RichTextBox Height="100" HorizontalAlignment="Left" Margin="306,30,0,0" Name="rtfMain" VerticalAlignment="Top" Width="200" />
rtfMain.Selection.Load(new FileStream(#"C:\temp\document.rtf", FileMode.Open), DataFormats.Rtf);

get absolute file path from image in WPF

I have something like this in my xaml:
<Grid>
<Image Name="image" Source="../../Images/DefaultImage.png" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></Image>
</Grid>
How can I get (using my code-behind C# code) the absolute path of the image source?
The method which works for me every time is this simple line
(YourImage.Source as BitmapImage).UriSource
In addition you can work on AbsolutePath or AbsoluteUri of UriSource returned according to your need.
When converted from a Uri string or filename, the ImageConverter creates a BitmapDecoder and extracts its first Frame. Getting the Uri should be possible with:
((BitmapFrame)image.Source).Decoder.ToString()
Note that this will generally return an absolute Uri rather than the original Uri found in the XAML. If you need the exact original Uri from the XAML, it is found in the _uri field of the BitmapDecoder but you'll need reflection and elevated code permissions to get to it, plus your code may not work in future NET Framework versions.
You could try this:
string path = ((BitmapImage)image.Source).UriSource.AbsolutePath;

Resources