【问题标题】:How to add a XAML Resource (Grid with ItemsControls) to a FlowDocument in Code-Behind multiple times如何在代码隐藏中多次将 XAML 资源(带有 ItemsControls 的网格)添加到 FlowDocument
【发布时间】: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


【解决方案1】:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-23
    相关资源
    最近更新 更多