Disabling text selection in DocumentViewer

2019-04-29 18:41发布

问题:

Simple question. How do you disable the text selection of DocumentViewer in WPF? This is the feature where an XPS document is displayed by the viewer and then text can be highlighted via mouse. The highlighted text can also be copied but I have already disabled this. I just don't know how to disable the highlighting.

Thanks!

回答1:

We have solved this by overriding the ControlTemplate of the ScrollViewer embedded in the DocumentViewer control. Insert the Style below in "Window.Resources":

<Style TargetType="{x:Type ScrollViewer}"  x:Key="CustomScrollPresenter">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ScrollViewer}">
                <Grid Background="{TemplateBinding Panel.Background}">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Rectangle Grid.Column="1" Grid.Row="1" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
                    <ScrollContentPresenter 
                        PreviewMouseLeftButtonDown="ScrollContentPresenter_PreviewMouseLeftButtonDown"
                        Grid.Column="0" 
                        Grid.Row="0" 
                        Margin="{TemplateBinding Control.Padding}" 
                        Content="{TemplateBinding ContentControl.Content}" 
                        ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" 
                        CanContentScroll="{TemplateBinding ScrollViewer.CanContentScroll}" />
                    <ScrollBar 
                        x:Name="PART_VerticalScrollBar"
                        Grid.Column="1" 
                               Grid.Row="0" 
                               Minimum="0" 
                               Maximum="{TemplateBinding ScrollViewer.ScrollableHeight}" 
                               ViewportSize="{TemplateBinding ScrollViewer.ViewportHeight}" 
                               Value="{Binding Path=VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource Mode=TemplatedParent}}" 
                               Visibility="{TemplateBinding ScrollViewer.ComputedVerticalScrollBarVisibility}" 
                               Cursor="Arrow" AutomationProperties.AutomationId="VerticalScrollBar" />
                    <ScrollBar 
                        x:Name="PART_HorizontalScrollBar"
                        Orientation="Horizontal" Grid.Column="0" Grid.Row="1" Minimum="0" 
                               Maximum="{TemplateBinding ScrollViewer.ScrollableWidth}" ViewportSize="{TemplateBinding ScrollViewer.ViewportWidth}" Value="{Binding Path=HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource Mode=TemplatedParent}}" Visibility="{TemplateBinding ScrollViewer.ComputedHorizontalScrollBarVisibility}" Cursor="Arrow" AutomationProperties.AutomationId="HorizontalScrollBar" />

                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Then override the Style of ScrollViewer with it in the ControlTemplate for DocumentViewer:

   <Style
      x:Key="MyDVStyleExtend"
      BasedOn="{StaticResource {x:Type DocumentViewer}}"
      TargetType="{x:Type DocumentViewer}">

      <Setter Property="Template">                
       <Setter.Value>

          <ControlTemplate TargetType="DocumentViewer">
                        <Border BorderThickness="2,2,2,2"
                    BorderBrush="SlateBlue" Focusable="False">
              <Grid Background="{StaticResource GridBackground}" 
                KeyboardNavigation.TabNavigation="Local">
                <Grid.ColumnDefinitions>                  
                  <ColumnDefinition Width ="*"/>                                    
                </Grid.ColumnDefinitions>                

                <ScrollViewer Style="{StaticResource CustomScrollPresenter}"  Grid.Column ="0" 
                  CanContentScroll="True"
                  HorizontalScrollBarVisibility="Auto"
                  x:Name="PART_ContentHost"
                  IsTabStop="True"/>

              </Grid>
            </Border>
          </ControlTemplate>
        </Setter.Value>
      </Setter>

    </Style>

Then create a function for the "PreviewMouseLeftButtonDown="ScrollContentPresenter_PreviewMouseLeftButtonDown"" attribute stated in the CustomScrollPresenter style.

  private void ScrollContentPresenter_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        e.Handled = true;
    }


回答2:

Another way would be to add e.g. a dockpanel:

<DockPanel Name="pnlTouchTaker" 
               VerticalAlignment="Bottom" HorizontalAlignment="Left"
               Background="Transparent">
    </DockPanel>

lying "above" the documentviewer and set it´s width and height to the actual width and height of the scrollviewer content in e.g. page loading event.

You might have to add additional logic if using zoom options and the horizontal toolbar becomes visible.



回答3:

you may use IsFocusable=false. But search box will be disabled too...



回答4:

Implement the following code in xaml.cs part (DocumentViewerInstance x:Name of your DocumentViewer in your xaml.)

DocumentViewerInstance.GetType().GetProperty("IsSelectionEnabled", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(DocumentViewerInstance, false, null);

You can use the IsFocusable=false or IsHitTestVisible = false or handle any preview event (for example in accepted answer) for disable selection but the hyperlinks won't work! If you set IsSelectionEnabled = false, the selection will be disabled but hyperlinks will work too. (Warning! IsSelectionEnabled can be changed for true value after you set false, so you should check the value often.)