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);
Related
The Problem
Here's a strange little quirk I ran into that I'm not sure how to fix. When I copy data from a DataGridTextColumn, if the text contains more than one space character (U+0020) in a row, all spaces except the first will be replaced with non-breaking spaces (U+00A0) in the pasted text.
I'll mention that this only happens with certain paste destinations, the one of particular concern being Excel. But I've confirmed that the problem does lie in WPF and not in the destination, as I'll demonstrate in a moment.
Code to Reproduce
Here's a very simple app so you can reproduce the problem.
A simple class to hold a string:
Public Class Foo
Public Sub New(Bar As String)
Me.Bar = Bar
End Sub
Public ReadOnly Property Bar As String
End Class
The back-end of a window:
Public Class MainWindow
Public ReadOnly Property Foos As New List(Of Foo) From {New Foo("A B"),
New Foo("A B"),
New Foo("A B")}
End Class
And the front-end of the window:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<DataGrid IsReadOnly="True" AutoGenerateColumns="False" ItemsSource="{Binding Foos}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Bar}"/>
</DataGrid.Columns>
</DataGrid>
</Window>
Note that in the MainWindow back-end code, those spaces between the As and Bs are all just normal spaces (U+0020). The first Foo has one space, the second has two spaces, and the third has three.
It will also be helpful to have a clipboard viewing tool, so you can see the data that's being copied (I used Inside Clipboard), and a tool to list out the Unicode character codes in a string (I used this website).
Steps to Reproduce
Run MainWindow, select the second cell in the DataGrid and copy it using Ctrl+C.
If you paste this directly into the web tool I linked above, you will see only normal spaces, but open or refresh your clipboard viewer and you'll see there are different formats available:
If you inspect the first two formats CF_TEXT and CF_UNICODETEXT, you should see that the spaces between A and B are still normal spaces (you can copy those values from the clipboard viewer into the web tool to verify this). But if you look at the HTML Format entry, you'll see this:
And so we reach the problem: while the text formats are being encoded correctly, the HTML format is being encoded with non-breaking spaces.
You can also test this using Excel. Excel will favor the HTML format by default when pasting. If you copy that same second cell from the DataGrid into Excel, it will paste the string containing non-breaking spaces, which you can verify using a formula, some VBA code, or by copying the text from Excel into the web tool. If you try Paste Special in Excel instead of normal Paste, you have the option of choosing which format to use as a source. Using either Text or Unicode Text results in output strings with normal spaces, as intended.
How Can I Fix This?
So that's the problem, copying and pasting from the DataGrid into Excel changes the string, and I need the string to stay the same. I don't know why this behavior occurs or how I would go about changing it or working around it.
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.
I am trying to externalise some of the wording within my WPF application, however I would like to be able to use some degree of formatting as well.
My initial thought was to use a string resource which represented a FlowDocument or Paragraph such as:
<FlowDocument>
<Paragraph FontSize="16" Foreground="Blue">Some display text under content management</Paragraph>
</FlowDocument>
In the UI I have been trying to bind this using a IValueConverter:
<ContentControl Content="{Binding Path=CMSText,Source={StaticResource Resources},Converter={StaticResource flowDocConverter}"/>
In the converter:
StringReader sr = new StringReader(value.ToString());
XamlReader xamlReader = XamlReader.Create(sr);
return (FlowDocument)xamlReader.Parse();
but it keeps throwing an exception on the return statement.
Is it even possible to do this via a binding?
And where am I going wrong in the XamlReader?
EDIT
XamlParseException
'Cannot create unknown type 'FlowDocument'.' Line number '1' and line position '2'.
Change your input string FlowDocument Tag, adding the NamePpace like so:
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:local="clr-namespace:MARS">
<Paragraph FontSize="16" Foreground="Blue">Some display text under content management</Paragraph>
</FlowDocument>
I'd say you simply cannot cast the result of xamlReader.Parse() into a FlowDocument (I'm not sure why).
you should rather try something like this as your converter:
FlowDocument myFlowDoc = new FlowDocument();
myFlowDoc.Blocks.Add(new Paragraph(new Run(value)))
return myFlowDoc;
(I find FlowDocument management lacks simplicity and tends to be a hassle)
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;
This should be simple, but...
I created a folder in my solution called Images. I dragged an image into it. How do I now display this image on a Page or View?
Make sure the image is set as a Resource. It can be in any folder in any of your projects in your solution.
You can then reference this as [assembly];component/[path]/[imagename.extension]
For example:
<Image Source="/mynamespace.myassembly;component/ResourcesFolder/image.png" Width="16" Height="16" />
There are a couple of ways to get at it--here's the way that involves setting the image as a Resource in the Visual Studio file properties:
using (var stream = Application.GetResourceStream(
new Uri("SilverlightAssemblyName;component/Images/myImage.png",
UriKind.Relative)))
{
// read from stream
}
Where SilverlightAssemblyName is replaced by the Assembly Name you specified in the Silverlight tab of your Silverlight project.
If you want to use the image in code:
var bitmap = new BitmapImage();
bitmap.SetSource(stream);
myImageControl.ImageSource = bitmap;
Or, if you want to use the resource in XAML, you don't need any of the code:
<Image Source="/Images/myImage.png" Width="16" Height="16" />