WPF文档查看器

时间:2017-11-02 11:09:31

标签: c# wpf xaml documentviewer

我有一个C#Wpf项目,我已成功加载了一个Xps。将文件存入文件查看器。我希望能够在我的C#代码中有一个变量,当您滚动文档时会注意到页面更改。 到目前为止,我已经发现,xaml代码有一个函数,如果滚动到下一页,它会自动更改页码:

    <DocumentViewer x:Name="viewDocument" HorizontalAlignment="Left" VerticalAlignment="Top" Height="Auto" Grid.Row="0" Grid.Column="0" >
            <FixedDocument></FixedDocument>
        </DocumentViewer>
    <TextBlock Text="{Binding ElementName=viewDocument,Path=MasterPageNumber}" Grid.Row="1"/>

我的最终目标是花费用户在每个页面上花费的时间,这就是为什么我需要能够将当前页码与我的代码中的变量连接起来,这是我不能用上面的例子做的。我试图实现一个INotifyPropertyChanged,但我是C#的新手,我找不到错误。它将变量设置为第一页,但之后它不会更新。

这是我的视图模型:

using System; using System.ComponentModel; 
namespace Tfidf_PdfOnly {
public class MainViewModel : INotifyPropertyChanged
{

    private int _myLabel;

    public int MyLabel
    {
        get
        {
            return this._myLabel;
        }
        set
        {
            this._myLabel = value;
            NotifyPropertyChanged("MyLabel");
        }
    }


    public MainViewModel()
    {
        _myLabel = 55;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}
}

,这是在我的Document_Viewer.xaml.cs文件

 XpsDocument document1 = new XpsDocument(path, System.IO.FileAccess.Read);
        //load the file into the viewer
        viewDocument.Document = document1.GetFixedDocumentSequence();

        MainViewModel vm = new MainViewModel();
        this.DataContext = vm;
        vm.MyLabel = viewDocument.MasterPageNumber; 

要查看它是否有效,我将其绑定到UI上的标签:

<DocumentViewer x:Name="viewDocument" HorizontalAlignment="Left" VerticalAlignment="Top" Height="Auto" Grid.Row="0" Grid.Column="0" >
            <FixedDocument></FixedDocument>
        </DocumentViewer>
    <TextBlock Text="{Binding MyLabel, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}" Grid.Row="1" HorizontalAlignment="Right"/>

我希望我的问题很明确,任何帮助都会被激活!

1 个答案:

答案 0 :(得分:1)

DocumentViewer有一个名为MasterPageNumber的属性(应该是文档的页面索引)。以下示例使用Prism和Blend SDK(行为)。转换器快速而肮脏。对于计时,您可以使用StopWatch实例来跟踪页面更改之间的时间长度。

MVVM方法

视图模型

public class ShellViewModel : BindableBase
{
    private int _currentPage;

    public string Title => "Sample";

    public string DocumentPath => @"c:\temp\temp.xps";

    public int CurrentPage
    {
        get => _currentPage;
        set => SetProperty(ref _currentPage, value);
    }

    public ICommand PageChangedCommand => new DelegateCommand<int?>(i => CurrentPage = i.GetValueOrDefault());
}

视图

<Window x:Class="Poc.MainWindow"
    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:viewModels="clr-namespace:Poc.ViewModels"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:behaviors="clr-namespace:Poc.Views.Interactivity.Behaviors"
    xmlns:converters="clr-namespace:Poc.Views.Converters"
    xmlns:controls1="clr-namespace:Poc.Views.Controls"
    mc:Ignorable="d"
    Title="{Binding Title}" Height="350" Width="525">
<Window.Resources>
    <converters:PathToDocumentConverter x:Key="PathToDocumentConverter"></converters:PathToDocumentConverter>
</Window.Resources>
<Window.DataContext>
    <viewModels:ShellViewModel />
</Window.DataContext>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
    </Grid.RowDefinitions>
    <DocumentViewer Document="{Binding DocumentPath,Converter={StaticResource PathToDocumentConverter}}">
        <i:Interaction.Behaviors>
            <behaviors:DocumentViewerBehavior PageViewChangedCommand="{Binding PageChangedCommand}"></behaviors:DocumentViewerBehavior>
        </i:Interaction.Behaviors>
    </DocumentViewer>
    <TextBlock Grid.Row="1" Text="{Binding CurrentPage}"></TextBlock>
</Grid>

行为

public class DocumentViewerBehavior : Behavior<DocumentViewer>
{
    public static readonly DependencyProperty PageViewChangedCommandProperty = DependencyProperty.Register(nameof(PageViewChangedCommand), typeof(ICommand), typeof(DocumentViewerBehavior));

    public ICommand PageViewChangedCommand
    {
        get => (ICommand)GetValue(PageViewChangedCommandProperty);
        set => SetValue(PageViewChangedCommandProperty, value);
    }

    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.PageViewsChanged += OnPageViewsChanged;
    }

    private void OnPageViewsChanged(object sender, EventArgs e) => PageViewChangedCommand?.Execute(AssociatedObject.MasterPageNumber);

    protected override void OnDetaching()
    {
        base.OnDetaching();

        AssociatedObject.PageViewsChanged -= OnPageViewsChanged;
    }
}

转换器

public class PathToDocumentConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var fileInfo = new FileInfo((string)value);

        if (fileInfo.Exists)
        {
            if (String.Compare(fileInfo.Extension, ".XPS", StringComparison.OrdinalIgnoreCase) == 0)
            {
                return new XpsDocument(fileInfo.FullName, FileAccess.Read).GetFixedDocumentSequence();
            }
        }

        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}