WPF FlowDocument Binding - wpf

I am using Microsoft's XAML/HTML converter to convert HTML from a database into a XAML string. The Microsoft converter seems to be formatting the text correctly, but I'm having trouble binding the output to a XAML object.
For example, using the following HTML:
<span style="font-weight: bold; font-family: Georgia; color: rgb(0, 96, 144); text-decoration: underline;">Hello world.</span>
I will get the XAML output:
<Section xml:space="preserve" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Paragraph>
<Run FontWeight="bold" TextDecorations="Underline" FontFamily="georgia">Hello world.</Run>
</Paragraph>
Assuming the HTML is coming into the WPF application as the "Text" property of a database object, I then use Binding and Converters like so:
<TextBlock Text="{Binding Path=ActiveDataItem.Text, Converter={StaticResource convertHTMLToXaml}}" />
Unfortunately, this just prints the XAML to the page and doesn't parse it. I'm assuming this is because I'm binding to the TextBlock and that's the expected outcome. My question is how do I bind this output a FlowDocument related control like a Paragraph, Run, Section, or whatever?
Note: I realize there a quite a few threads dedicated to converting HTML to XAML. I have referenced most of them, but they are all lacking on this specific step. Any help or links are appreciated, thanks in advance.

For your example, you have the xaml as text and bound to the Text-property. This only shows the xaml as text.
If there is a direct way to bind it as the content of a FlowDocument, I don't known. IMO this is not possible due to the structure of FlowDocument. But maybe someone knows a way and posts you a solution for this.
To do it manually, look at the example of this page (dead link, see Archive.org). There I have seen that the author loads a XAML-string into a RichTextBox. You can change the code to your needs (RichtTextBox works also with FlowDocs). Search for public static class RichTextboxAssistant, there is the code your looking for. Take care for the encoding. He uses ASCII. Maybe you have to change this to UTF.
Hope this helps.

For .NET versions previous to 4.0: In this link, Vincent Van Den Berghe explain how to extend FlowDocument to support 'Bindable Runs', check it out
For .NET 4.0: Run.Text property is bindable

Related

SelectedItem of SelectedItem

first of all I would like to thank you for the many good posts that i read in this forum. Unluckily I could not find anything of help for my current problem (either here or anywhere else).
What I'm trying to do sounds quite simple, but I have no clue how to get it to work ... perhaps I'm still to new to wpf or I don't thing wpfy enough :)
I'm designing a front end for a part in an automated manufacturing:
I have a quantity of places where pallets can be put (but it can be empty as well).
Each pallet has up to 3 places where parts can be mounted
Everything is created dynamically of a database and is reacting to changes.
The position of the parts on the pallet comes from the database as well and should be visualized
What I would like to have is:
An overview over the pallet-places with a preview of the pallet
When I select a place I want to see a detail view of the place
When I click on a part on the pallet of the detailed pallet I want to see details to the part
The first two points are quite simple and work nicely:
I have got a DataTemplate for every component (part, pallet, pallet-place). Actually those are UserControls that are imported as Datatemplates
the overview is a ListBox with the places as DataContext
for the detail-place-view I use the UserControl and bound it to the SelectedItem of the Listbox
I tried to bind the Text of a Textblock to the ID of the selected Part ... and fail.
Probably I could use some global variables in the code behind - but that sound very ugly.
Can anybody help?
I have got a solution ... it is not nice but works.
I created an event in the pallet, that triggers, when the selected part-place changes
I handle the event in the pallet-place and create a new one
And finally I handle it in the overview and change the detailview accordingly
Most likely there are much nicer solutions, but it will suffice.
Perhaps try an ElementName binding?
<TextBlock Text="{Binding ElementName=Name_of_your_Listbox, Path=SelectedItem.ID" />
Can you post a bit more code of your TextBlock and your Binding?
Context is important, if i use a ContentControl and bind its content to the SelectedItem like this:
<ContentControl Content="{Binding SelectedItem, ElementName=mylistbox}">
I can bind to the ID of the selected item in the DataTemplate like this:
<ContentControl.ContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding ID}" />
</DataTemplate>
</ContentControl.ContentTemplate>
That is because setting the Content of the ContentControl automatically sets the DataContext as well, and this binding is relative to the DataContext since no source (ElementName, RelativeSource, Source) has been specified.
I do not know how your UserControl handles the context, if the DataContext is not affected such bindings will not work. You would need to bind directly then:
<uc:MyDetailsView Data="{Binding SelectedItem, ElementName=mylistbox}">
<!-- ... -->
<TextBlock Text="{Binding SelectedItem.ID, ElementName=mylistbox}" />
This of course defeats the purpose of having the binding on the UserControl itself in the first place. But unless you post some relevant code it's quite hard to tell what is wrong.
Also check the Output window in VisualStudio, binding errors will show up there and might provide valuable information as to what went wrong.

How to supply a design time value for silverlight textblock that is bound to viewmodel property?

I have a TextBlock in my XAML that has its text bound to a property in my viewmodel.
<TextBlock x:Name="SomeText" Text="{Binding TheTextProperty}" />
This works fine, but at design time, there is no viewmodel so the property is unresolvable and the text is blank. This is hard to work with in the designer because it shows no visible text.
How can I specify some default text to use at design time?
Maybe you could try
<TextBlock x:Name="SomeText" Text="{Binding TheTextProperty, FallbackValue='Some other text'}" />
as documented here.
You can also use Design Time Data to provide a rich binding experience in your solution. Its a little hard to set up and get running, but here's the gist.
First, you create your DataContext in xaml. Add a new Xml document to your solution (the root is a good place) and give it an .xaml extension. Lets call this file "foo.xaml" for this example.
In this file, remove all of the XML and start creating an instance of your DataContext type. For example, if your DataContext was a string (very simple example) your file would look like the following:
<string xmlns="clr-namespace:System;assembly=mscorlib">LOL!</string>
You might have yours look like
<ViewModel xmlns="clr-namespace:MyNamespace">
<ViewModel.MyObservableCollection>
<MyModel Name="foo" />
<!-- etc -->
Set the Build Action on this file to DesignDataWithDesignTimeCreatableTypes:
Next, in your View, add the following namespaces and properties to the root of your Window/UserControl:
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DataContext="{d:DesignData Source=foo.xaml}"
Source is relative to the current document. So, if your solution looked like
Views
MyUserControl.xaml
Data
foo.xaml
you would set the Source to ../Data/foo.xaml.
There are other ways to create a DesignData context depending on whether your ViewModel can be instantiated at design time, etc.
Another option is to use the DesignerProperties.GetIsInDesignMode function to determine if the control is hosted in VS/Blend and Generate a fake DataContext in that case. Laurent Bugnion provides a number of examples of how to create and use design-time data in this post

Silverlight xaml TextBlock.Text with CDATA not showing up at runtime?

The following xaml causes the text "Activate a test to the left." to be visible at run-time and at design-time (in Vs2010):
<TextBlock TextWrapping="Wrap">
<TextBlock.Text>Activate a test to the left.</TextBlock.Text>
</TextBlock>
The following shows nothing at run-time, but the text IS visible at design-time:
<TextBlock TextWrapping="Wrap">
<TextBlock.Text><![CDATA[Activate a test to the left.]]></TextBlock.Text>
</TextBlock>
What's the problem?
Here is an extensive discussion on this very topic:
http://forums.silverlight.net/forums/t/187623.aspx
The designer view can often be different from what you actually see at runtime. The designer does not run all the code just some of it, it makes some heuristic assumptions and its based on WPF not Silverlight.
So especially for Silveright apps what you see is not necessarily what you get.
Evidentently the Silverlight Xaml parser doesn't take to kindly to the CDATA section. Why would you do that anyway?

Can you view XAML as "regular" .net code (c#\vb.net)?

There are times when I find some example XAML that I want\need to do in code (c#\vb.net).
I assume at some point the XAML becomes code, or at least IL.
So my questions:
Am I correct in assuming that XAML is converted to IL? (or if not IL what does it become?)
If the above is correct, when does XAML become IL (or whatever it becomes)?
Is there some way to see the XAML in as "code"
Thanks.
No, XAML does not compile into IL, that gets done at runtime. The best way to think about it is as a way to compose an application from components.
For the majority of things you can replicate in C# what you do in XAML, however there is a small number of things that is available in XAML that's not in C# and vice versa. Charles Petzold at some point said that ostensibly, XAML looks like XML, but it's actually not, it's a language of its own.
For example this XAML code:
<Grid>
<TextBlock Text="Something" />
</Grid>
Is equivalent to the following C# code. This will get done in C# at runtime and short of setting a breakpoint in a particular component's constructor, there isn't much you can do to figure out what executes at runtime.
var grid = new Grid();
grid.Children.Add(new TextBlock{Text = "Something"});
I am sure there is a solution to your problem, but not as an answer to this particular question. Can you give more details on your problem and we can help you understanding it.
WPF and Silverlight treat XAML differently; neither convert XAML to IL. WPF's markup compiler converts XAML to a compiled form called BAML that is a binary version of the XAML. Silverlight leaves the XAML as plain text (compressd in the .XAP) and parses it at runtime.
Is there some way to see the XAML in
as "code"
If you are talking about the hierarchy of controls in xaml, then you may use myControl.Parent.
You can "see in code" how the controls in xaml are nested. You will also get/set their properties.

WPF Styles Question

A simple question which I can't find the answer on the web for some reason...
I want to place the content to a ResourceDictionary:
<TextBlock
Style="{StaticResource HomePageTextStyle}">
<LineBreak/>
Hello<LineBreak/>
<Bold>World!</Bold>
<LineBreak/>
</TextBlock>
The best I could do was:
<s:String x:Key="HomePageTextContent">
Hello World!
</s:String>
Which stripped all the formatting from the content :( Help please~ Thanks in advance. Oh, and If you can recommend a nice reference for using WPF Styles, it would be great~ Thanks!
I'd say you want to use data-binding instead of applying a style, since you are putting content in the TextBlock not changing the appearance of the TextBlock itself, e.g. drawing a border around it.
According to MSDN: TextBlock supports the hosting and display of Inline flow content elements. To be more precise, the content of the TextBlock in your first code block becomes a InlineCollection in the Inlines property of the TextBlock. Unfortunately the Inlines property isn't a dependency property so we can't bind data to it. The Text property, on the other hand, is a dependency property but doesn't allow anything other than a String.
To make a long story short, I don't think you can achieve what you want using pure XAML.

Resources