How to bind data with the rich text box with MVVM pattern? - c#

How to bind data dynamically with the document property of the rich textbox. I am using MVVM in Wpf with c#?
EDIT:
I tried with this example in "codeproject.com/KB/WPF/BindableWPFRichTextBox.aspx"; but i can't understand what is happening in that example. I am very new to WPF and MVVM.
It's throwing error in the line
try {
var stream = new MemoryStream(Encoding.UTF8.GetBytes(GetDocumentXaml(richTextBox)));
var doc = (FlowDocument)XamlReader.Load(stream);
// Set the document
richTextBox.Document = doc;
}
catch (Exception) { richTextBox.Document = new FlowDocument(); }
the error is like "Data at the root level is invalid. Line 1, position 1." i am giving value like "Sample Text"
I found the xaml text should be like
<FlowDocument PagePadding="5,0,5,0" AllowDrop="True" xmlns="schemas.microsoft.com/winfx/2006/xaml/… generated by app back-end</Paragraph>
</FlowDocument>" But how to get this text?

I hope I interpret your question correctly:
I assume you are binding to a normal string (sample text) with the RichTextBox you got from codeproject. This will not work, 'cause the Document you have to bind is a FlowDocument and it has a specific format. If you assign a string you will get the error "data invalid" when it tries to create a FlowDocument from the string
Here's a link on how to create a FlowDocument via XAML or via CodeBehind.
http://msdn.microsoft.com/en-us/library/aa970909.aspx
Then the converter comes into play: Out of the string representation it creates a real FlowDocument.
So, if you want to display your sample text bind to a string in the VM like this:
<FlowDocument PagePadding=\"5,0,5,0\" AllowDrop=\"True\" "
+ "xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">"
+ "<Paragraph>Your sample text</Paragraph></FlowDocument>"

Related

Find original SOURCE attribute value

I have an application where I'm taking a XAML template from a database record, plugging in new text strings and image references, and showing it in a window.
I take the XAML text and create a DependencyObject using this property:
public DependencyObject ParsedXamlTree
{
get
{
String xaml;
DependencyObject theDependencyObj;
xaml = ProcessedXaml;
byte[] xamlData = Encoding.Unicode.GetBytes(xaml);
using (MemoryStream ms = new MemoryStream(xamlData))
{
theDependencyObj = (DependencyObject)XamlReader.Load(ms);
}
return theDependencyObj;
}
}
Within the XAML will be an Image tag. For example:
<Image x:Name="categoryImage"
HorizontalAlignment="Center"
Height="240"
Margin="72,42,408,318"
VerticalAlignment="Center"
Width="320"
Source="SampleAssets\pacman-151558_640.png"/>
The problem I'm having is that when I parse the DependencyObject tree and get to the corresponding Image object, the string "SampleAssets\pacman-151558_640.png" from the Source attribute seems to be missing.
I notice that when it reads and parses the XAML, there is an IO exception being thrown within WPF itself. That's the line where XamlReader.Load is called. This exception is caught within the library so I'm only seeing evidence of it in the debug trace window.
I'm guessing that it's trying to find "SampleAssets\pacman-151558_640.png" for the Image tag and failing. That's fine in itself, as I always figured the image sources would have to be patched up at runtime.
The question is, how do I retrieve the "SampleAssets\pacman-151558_640.png" string that was in the original XAML? Is there somewhere in the Image object I can get this?
Worst case scenario would be parsing the XAML myself to find the tag and extracting the attribute string from it, but I'm hoping that's not necessary.
WPF has a built-in type converter (ImageSourceConverter) that converts URI strings to ImageSource objects (the type of the Image.Source property). If an image could not be loaded from an URI string, the converter returns null, so the Source property of your Image control will also be null.
There is nothing in the object tree that will keep the URI of a non-available image. You will have to parse the XAML Template before loading and replace invalid image URIs by valid ones.

Android Webview equivalent in Windows Phone 8 app

I have text with some HTML tags in it.
Example : <I> I Play Football and Cricket </I>
Now when i try to display this text in Textblock it displays with Italics tag <I> as well.
The data is present in the XML file and i am working on Windows Phone 8 application.
In Android we use Webview, but what do i need to use here ?
EDIT
I have tried using TextBlock with inlines:
Italic itlText = new Italic();
itlText.Inlines.Add(new Run() { Text = "This is some example text in italics" });
Inilinetext.Inlines.Add(itlText);
It works good But issue here is suppose i have a text like below.
"This is text in <I>Italics</I> here"
Now it display entire text in italics.
This depends on how much content you want to display. If you will show large amount of HTML text, use WebBrowser control for that.
In case you only have a couple of tags i, em, b or strong, then you can actually use TextBlock, but you would have to do the parsing yourself then in order to convert the HTML to the suitable XAML components.
You also have to ask yourself how many such controls you need to display on a single page. If the answer is a few, use the WebBrowser then. If you need to display lots of them, say you have a chat or a feed, then the second route would be better.
EDIT:
Use the following code:
Inilinetext.Inlines.Add(new Run() { Text = "This is text in " });
Inilinetext.Inlines.Add(new Run() { Text = "Italics", FontStyle = FontStyle.Italic });
Inilinetext.Inlines.Add(new Run() { Text = " here" });
I told you you have to parse the original string to see which parts are italic and which are not.

Text doesn't display correctly when loaded from SQL DB

I use FreeTextBox for my webpage. And when I load the text again from Database to display on a Label, it doesn't display correctly( still contain HTML tag: ,...)
Take a look at my code below ( load the text from the DB)
Datatable db= excute .....;
string content = db.Rows[0]["CONTENT"].toString();
Label1.Text= content;
Just a basic codes , I really don't know where is the mistake.
Label1.Text ----> Demo freetextbox<div> just a simple demo</div><div>dnalksdfasdflklsd</div>
Label1.Text = HttpUtilities.HtmlDecode(content);
It decode the text, and the text will be displayed correctly.

Printing a flowdocument with dynamic data in WPF

I am trying to find a good way to print a flow document in WPF. What I want is to have a possibility to see how the document turns out as I design it, so therefore creating a pure FlowDocument as a XAML is out of the questions (as Visual Studio wont show the design view for it).
So what I have done now is to create a window that contains a FlowDocument like this (some excessive parts have been removed to make the code more consise):
<Window x:Class="MyNamespace.ProjectPrintout...>
<Grid>
<FlowDocumentReader>
<FlowDocument ColumnWidth="500" Name="Document">
<!-- Header -->
<Paragraph Name="HeaderText">
The header will go here
</Paragraph>
</FlowDocument>
</FlowDocumentReader>
</Grid>
</Window>
This is a bit strange since I will never show this Window to the user, and I only wrap the FlowDocument with a Window so that I can see how it looks like as I develop it. This Ican live with.
So somewhere else in my application, I want to print this FlowDocument to the default printer, but I also have to set the header dynamically (in addition to many other parts of the documents that needs dynamic data that are omitted here).
The code to print looks like this:
var printout = new ProjectPrintout();
printout.HeaderText= new Paragraph(new Run("Proper header text"));
var document = printout.Document;
var pd = new PrintDialog();
IDocumentPaginatorSource dps = document;
pd.PrintDocument(dps.DocumentPaginator, "Document");
The document is getting printed, and looks fine except that the header text still shows "The header will go here", even if I replaced it from my code with "Proper header text". I also tried changing it like this:
(printout.HeaderText.Inlines.FirstInline as Run).Text = "Proper header text";
But the result is the same.
So the question is: How can I change the contents in the FlowDocument from code before I print it, or are there a better way to do this instead of my approach?
MVVM to the rescue:
Epiphany: UI is not Data. UI is not a data store. UI is meant to show Data, not to store it.
1 - Create a simple object to hold your data
public class MyDocumentViewModel: INotifyPropertyChanged //Or whatever viewmodel base class
{
private string _header;
public string Header
{
get { return _header; }
set
{
_header = value;
NotifyPropertyChange(() => Header);
}
}
//Whatever other data you need
}
2 - Define Bindings in your Document;
<Paragraph>
<Run Text="{Binding Header}"/>
</Paragraph>
3 - Set your FlowDocument's DataContext to an instance of this class:
var flowdoc = new YourFlowDocument();
var data = new MyDocumentViewModel { Header = "this is the Header" };
//whatever other data
flowdoc.DataContext = data;
//do the printing stuff.

Rich Text box Properties problem

<RichTextBox AcceptsTab="True" ForceCursor="True" IsDocumentEnabled="True" TextChanged="ContentChanged" Name="TextContent"/>
In C# file i am not able to get Text property of Rich Textbox.
I am trying to get this like;
TextContent.Text= "hello"
But it is giving compile time error.
'System.Windows.Controls.RichTextBox' does not contain a definition for 'Text' and no extension method 'Text' accepting a first argument of type 'System.Windows.Controls.RichTextBox' could be found (are you missing a using directive or an assembly reference?)
Please suggest me.
Generally, you need to work with Blocks property. But, if you are using FlowDocument for representing RichTextBox content, then you can access text with Document property.
For example, writing content:
XAML:
<RichTextBox Name="rtb">
</RichTextBox>
Code:
FlowDocument contentForStoring =
new FlowDocument(new Paragraph(new Run("Hello, Stack Overflow!")));
rtb.Document = contentForStoring;
To read content you simply access Document property:
FlowDocument yourStoredContent = rtb.Document;
If you need just to take text, you have more simple way - TextRange class. Next code will retrieve all text content:
TextRange storedTextContent =
new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);
string yourText = storedTextContent.Text;
If you want to retrieve the text from the rich text box then use this code,
string content = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd).Text;

Categories