WPF DataTemplate 获取 Flowdocument

WPF DataTemplate get Flowdocument

我的 EvenementViewModel 有两个 DataTemplate,一个用于只读 (LectureEvenement),第二个用于写入 (EditeurEvenement)。 根据 EvenementViewModel 状态选择模板。这些模板在 TabControl 中使用。

从后面的代码(单击按钮),我想获取只读 DataTemplate 中的 FlowDocument。目标是打印 FlowDocument。

我需要帮助来获取 TabControl 的选定选项卡中的 FlowDocument 句柄。

有什么建议吗?

有部分 XAML 代码。

<Window.Resources>
    <DataTemplate x:Key="EditeurEvenement" DataType="{x:Type local:EvenementViewModel}">
        <ScrollViewer Name="Conteneur" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
            <StackPanel MaxWidth="1000">
                <Border BorderThickness="5" BorderBrush="#55CDD7E1">
                    <StackPanel Background="#55CDD7E1">
                        <!-- Centrale -->
                        <StackPanel DockPanel.Dock="Top" Margin="0,0,0,5" HorizontalAlignment="Left">
                            <TextBlock VerticalAlignment="Center"><Run Text="Centrale :" FontWeight="Bold"/></TextBlock>
                            <ComboBox MinWidth="160" ItemsSource="{Binding ListeCentrale}" DisplayMemberPath="Nom" SelectedItem="{Binding Centrale}"/>
                        </StackPanel>
...
                        </StackPanel>
                </Border>
            </StackPanel>
        </ScrollViewer>
    </DataTemplate>

    <DataTemplate x:Key="LectureEvenement" DataType="{x:Type local:EvenementViewModel}">
        <FlowDocumentScrollViewer VerticalScrollBarVisibility="Auto">
            <FlowDocument FontFamily="Sergoe UI" FontSize="12px" Name="FdEvenement">
                <Paragraph>
                    <!-- Centrale -->
                    <TextBlock Margin="0,0,0,5"><Run Text="Centrale : " FontWeight="Bold"/><Run Text="{Binding Centrale.Nom, Mode=OneWay}"/></TextBlock>
                    <LineBreak/>
...
                </Paragraph>
            </FlowDocument>
        </FlowDocumentScrollViewer>
    </DataTemplate>

    <DataTemplate DataType="{x:Type local:EvenementViewModel}">
        <ContentControl Content="{Binding}">
            <ContentControl.Style>
                <Style TargetType="{x:Type ContentControl}">
                    <Setter Property="ContentTemplate" Value="{StaticResource LectureEvenement}"></Setter>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding EstModifiable}" Value="True">
                            <Setter Property="ContentTemplate" Value="{StaticResource EditeurEvenement}"></Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
    </DataTemplate>
</Window.Resources>

    <TabControl x:Name="TcEvenements" ItemsSource="{Binding ListeOngletOuvert}" SelectedItem="{Binding OngletSelectionne}">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding TitreTab}" Margin="0,0,5,0" VerticalAlignment="Center"/>
                    <Button CommandParameter="{Binding DataContext, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" Command="{Binding LancerFermer}">
                        <Image Source="Icone/icons8-delete-23.png" Width="15"/>
                    </Button>
                </StackPanel>
            </DataTemplate>
        </TabControl.ItemTemplate>
    </TabControl>

无论何时应用您的模板,FlowDocumentScrollViewer 元素都是 TabControl 的视觉子元素。然后,您可以使用 VisualTreeHelper class:

获取对它的引用
private void Button_Click(object sender, RoutedEventArgs e)
{
    FlowDocumentScrollViewer fdsv = FindVisualChild<FlowDocumentScrollViewer>(TcEvenements);
    if (fdsv != null)
    {
        FlowDocument fd = fdsv.Document;
        //...
    }
}

private T FindVisualChild<T>(Visual visual) where T : Visual
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
    {
        Visual child = (Visual)VisualTreeHelper.GetChild(visual, i);
        if (child != null)
        {
            T correctlyTyped = child as T;
            if (correctlyTyped != null)
            {
                return correctlyTyped;
            }

            T descendent = FindVisualChild<T>(child);
            if (descendent != null)
            {
                return descendent;
            }
        }
    }

    return null;
}