Best control for hosting portions of WordML (docx)
-
Wednesday, May 16, 2007 8:54 PM
Hi,
I'm working on a xaml app that can be used to browse portions of wordML (docx) files. I was wondering if there is any inherent support for plopping the content of a docx into a specific control? I know that wordML is fairly flat and FlowDocuments are fairly flat so doing that parsing so that hierarchical relationships are reflected is a little cumbersome - I am trying to avoid that.
Here's an example. If I were doing a Photo Gallary-style app, I would do something like the below and have an <image Source="foo.jpg" /> where the xxxxx is below.
If I want the same look and feel, but with textual items instead of graphics - and based off of xpath'ing into a wordML document, what control would be ideal?
<(somecontrolname) XPath="//w
/w:r" Height=whatever /><stuff>
......
<Listbox>
<ListBox.ItemTemplate>
<DataTemplate>
xxxxx
</DataTemplate>
</ListBox.ItemTempalte>
......
</Listbox>
......
</stuff>
Any help would be greatly appreciated - I figure there is something that is probably obvious and I'm just a wee new to know it.
Thanks,
D
All Replies
-
Thursday, May 17, 2007 4:02 AMModerator
Well, first off, you seem to be headed down the right path already. What you can do is use an XmlDataProvider bound to the WordML file and then use XPath to reach into the document and pull out the elements you want. Then, once you have the nodes that represent the data you're interested in, you can simply present the nodes with a DataTemplate. The DataTemplate gives you carte blanche as to how you present the data (i.e. could be a simple TextBlock, could be an Image, could be a rotating 3D cube!).
If you need more help than this, please feel free to follow up. If you do, please provide some more exact details so we can try and give you concrete examples.
Cheers,
Drew -
Thursday, May 17, 2007 3:06 PM
Thanks Drew!
That ended up being exactly my approach - but I am still slightly struggling with what content controls for my datatemplate would be ideal. I'll drop some of my code in here, and point out what I'm not exactly satisfied with-
As you can see below, within my DataTemplate, I just used another ListView. I tried a TextBlock initially, but I could only get one TextBlock within the DataTemplate, and I really want to have multiple XPath expressions populate multiple "items" within the control, within the list. So for example, I want to be able to XPath in, grab a heading title, grab the following paragraph, and display those in one cohesive control that I could later drag and drop etc. And then I'm going to get a control for each such heading in the doc, and hopefully get them to display hierarchically.
Still in the early stages of all that - what I was experimenting with was using a nested ListView as the control and using its subordinate ListViewItems as my XPath populated "items" . This introduces a few problems like having to disable the ability to click on each ListViewItem independently (I don't want the Heading, for example, to be highlighted if the user clicks their mouse inside the block) and having to deal with wrapping text (currently text doesn't wrap in the below code).
So I got to thinking - there has to be a better control/approach where these extra steps don't need to be taken. Should I be using a flow document in my datatemplate?
Any ideas?
Code Snippet<ListBox x:Name="docParts" Background="White" Grid.Row="1" Grid.Column="1" ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
<ListBox.ItemsSource>
<Binding Source="{StaticResource w:documentDS}"
XPath="/w:document/w:body//w:p[w:pPr/w:pStyle[contains(@w:val, 'MySecretHeadingStyle')]]" />
</ListBox.ItemsSource>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<ListView Width="100" LayoutTransform="{StaticResource zoomSlider}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<!--Heading Title-->
<ListViewItem>
<Binding XPath=".//w:t" />
</ListViewItem>
<!--Heading Value-->
<ListViewItem>
<Binding XPath=".//w:pStyle/@w:val" />
</ListViewItem>
</ListView>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox> -
Thursday, May 17, 2007 3:19 PMModerator
Demi,
Hey, ok... the reason you could only put one TextBlock in there is because DataTemplate can only have one child element. Since you want multiple elements you should make your root element a panel, such as a StackPanel. Something like:
Code Snippet<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding XPath=...foo...}" /><TextBlock Text=" " /><TextBlock Text="{Binding XPath=...bar...}" />
</StackPanel>
</DataTemplate>
Note: the second TextBlock there creates a space, you can't just leave whitespace due to XML rules.
I think you could really solve this whole thing with just the main ListBox and the DataTemplate or just a ListView by itself. I don't know that you need to nest any lists yet based on what I see in your example.
HTH,
Drew -
Thursday, May 17, 2007 4:05 PM
I knew there was a pretty obvious solution

I still have plenty of work ahead to get some of the hierarchical stuff working - but the DataTemplate clarification "broke the seal" as far as the original question in this thread goes.
Thanks for being patient with us newbs, Drew!

