【发布时间】:2020-12-20 09:59:58
【问题描述】:
我正在开发一个 WPF 窗口,它在 FlowDocumentViewer 中显示一些技术计算的结果。
问题:FlowDocument 及其所有内容都是从 Code-Behind 创建的,因为每个计算在标题、显示的结果和行方面都略有不同。我使用不同的 BlockUIContainers 来保存带有一些 ItemsControls 的资源网格,以按格式化顺序显示结果并将其添加到 Section 中,然后添加到 Document 的 Blocks 中,但只有最后一个 Block 显示在 Reader 中。 我不明白为什么多次使用 FlowDoc.Blocks.Add(section) 后,只显示最后一个 Block。
我在 XAML 代码中创建了一个资源,以便从代码后面用结果填充它。我需要输出看起来像这样,例如:
M,ed = 70 kNm
Q,ed = 25 kN
N,ed = 30 kN
...
为了实现这样的格式设置,我创建了一个包含三列的网格,每列包含一个 ItemsControl 和一个 DataTemplate TextBlock,它绑定到一个结果列表。
<Window x:Class="FaceplateInput.Output"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FaceplateInput"
mc:Ignorable="d"
x:Name="OutputWnd"
WindowStartupLocation="CenterScreen"
Title="Output" Height="1000" Width="700">
<Window.Resources>
<Grid x:Key ="TestGrid" x:Name="Grid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ItemsControl x:Name="ItemsLeft" Grid.Column="0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl x:Name="ItemsMid" Grid.Column="1">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl x:Name="ItemsRight" Grid.Column="2">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window.Resources>
...
<FlowDocumentScrollViewer x:Name="DocReader" Grid.Column="1" Grid.Row="2" Margin="20" MaxWidth="700">
</FlowDocumentScrollViewer>
</Grid>
</Window>
我想在 Code-Behind 中创建 FlowDocument 以控制格式,特别是因为该文档是从计算类返回的单个字符串创建的。
我构建了以下测试方法来查看 FlowDocuments 是如何工作的。结果是只有添加的段落和最后一部分显示在输出窗口中。
代码隐藏:
namespace FaceplateInput
{
public partial class Output: Window
{
public string PathToImage;
public string PathToBackground;
public string PathToTXTFile;
public Output()
{
InitializeComponent();
CreateFlowDocument();
}
private void CreateFlowDocument()
{
FlowDocument FlowDoc = new FlowDocument();
List<string> leftStr = new List<string>();
List<string> midStr = new List<string>();
List<string> rightStr = new List<string>();
//for Testing purposes, i create some weired data to fill the Lists
for (int i = 0; i < 10; i++)
{
leftStr.Add($"LeftLine {i + 1}");
midStr.Add("=");
rightStr.Add($"RightLine {i + 1}");
}
//Creating a new Container with Resource Grid as UIElement:
BlockUIContainer cont = new BlockUIContainer((UIElement)this.FindResource("TestGrid"));
Grid child = (Grid)cont.Child;
//setting the sources for the ItemsControl:
ItemsControl items1 = (ItemsControl)child.Children[0];
items1.ItemsSource = leftStr;
ItemsControl items2 = (ItemsControl)child.Children[1];
items2.ItemsSource = midStr;
ItemsControl items3 = (ItemsControl)child.Children[2];
items3.ItemsSource = rightStr;
//adding section holding BlockUIContainer to Document
Section section = new Section();
section.Blocks.Add(cont);
FlowDoc.Blocks.Add(section);
//disconnecting UIContainer from parent to avoid Exception
section.RemoveChild(cont.Child);
cont.Child = null;
//another "testline" to see where it puts it in the document
FlowDoc.Blocks.Add(new Paragraph(new Run("TestString 1\n")));
//all the stuff above again to test
leftStr.Clear();
midStr.Clear();
rightStr.Clear();
leftStr.Add("______");
midStr.Add("_____________________");
rightStr.Add("_____________________");
for (int i = 0; i < 20; i++)
{
leftStr.Add($"Left: {(double)i * 324 / 10}\n");
midStr.Add("=\n");
rightStr.Add($"{(double)i * 13 / 2}\n");
}
BlockUIContainer cont1 = new BlockUIContainer((UIElement)this.FindResource("TestGrid"));
Grid child1 = (Grid)cont1.Child;
items1 = (ItemsControl)child1.Children[0];
items1.ItemsSource = leftStr;
items2 = (ItemsControl)child1.Children[1];
items2.ItemsSource = midStr;
items3 = (ItemsControl)child1.Children[2];
items3.ItemsSource = rightStr;
Section section1 = new Section();
section1.Blocks.Add(cont1);
FlowDoc.Blocks.Add(new Paragraph(new Run("TestString 2\n")));
FlowDoc.Blocks.Add(section1);
FlowDoc.Blocks.Add(new Paragraph(new Run("TestString 3\n")));
DocReader.Document = FlowDoc;
}
//...
}
}
我会很感激任何关于如何让它工作的提示,也许如何改进代码本身,或者任何关于完全不同方法的想法。 问候和谢谢,Crawliiee
【问题讨论】:
-
在网格资源上设置
x:Shared="False"。参见例如这里:stackoverflow.com/a/22960568/1136211 -
@Clemens, ty for the advice.Unfortunately, x:Shared="False" 并没有帮助显示所有添加的块,但是将此行添加到网格资源中,我可以摆脱断开连接BlockUIContainer 通过代码隐藏。
标签: c# wpf xaml resources flowdocument