一、實現功能:數組
二、關注詞:架構
三、靜態組織:
界面xaml:app
<!-- Annotations List --> <ListBox Name="annotationsListBox" Grid.Row="2" SelectionChanged="annotationsListBox_SelectionChanged" ItemsSource="{Binding}" Template="{StaticResource AnnotationsListTemplate}" ItemTemplate="{StaticResource AnnotationDataTemplate}" />
ListBox模板Template:簡單設置豎滾動條+StackPanel容器ide
<!--To Replace ListBox Template with Template that Allows TextWrapping and also provides a vertical scrollbar when the wrapped text extends below the bottom of the list box --> <ControlTemplate x:Key="AnnotationsListTemplate"> <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" > <StackPanel IsItemsHost="True" /> </ScrollViewer> </ControlTemplate>
ListItem的數據模板:spa
<!-- Data Template for Annotation Item that shows when an annotation was created, and what data the annotation contains. --> <DataTemplate x:Key="AnnotationDataTemplate"> <TextBlock Margin="5" TextWrapping="Wrap"> <TextBlock FontWeight="Bold" TextWrapping="Wrap"> [<TextBlock Text="{Binding Path=CreationTime}" />] </TextBlock> <TextBlock Text="{Binding Path=Cargos[1].Contents[0].InnerText,Converter={StaticResource AnnotationDataConverter}}" TextWrapping="NoWrap" /> </TextBlock> </DataTemplate>
綁定轉換string》TextRange.Text(Xml包含的Xaml數據轉換爲文本Text格式數據:code
public class AnnotationDataConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { // Convert 64 bit binary data into an 8 bit byte array and load // it into a memory buffer var data = System.Convert.FromBase64String(value as string); using (var buffer = new MemoryStream(data)) { // Convert memory buffer to object and return text var section = (Section) XamlReader.Load(buffer); var range = new TextRange(section.ContentStart, section.ContentEnd); return range.Text; } } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => null; }
主窗口內容須要一些私有字段協助運行:xml
private IAnchorInfo _info;//提供批註的錨定信息類 private AnnotationService _service;//批註服務類 private AnnotationStore _store;//批註存儲區 private Stream _stream;
四、運行流程:
主窗口初始化時設置好批註存儲導入及綁定到ListBox顯示對象
private void MainWindow_Loaded(object sender, RoutedEventArgs e) { // Load annotations store _stream = new FileStream("storage.xml", FileMode.OpenOrCreate); _service = new AnnotationService(flowDocumentReader); _store = new XmlStreamStore(_stream) {AutoFlush = true}; _service.Enable(_store); // Detect when annotations are added or deleted _service.Store.StoreContentChanged += AnnotationStore_StoreContentChanged; // Bind to annotations in store BindToAnnotations(_store.GetAnnotations()); }
批註內容變更,觸發事件,需從新綁定批註內容到ListBox更新顯示排序
private void AnnotationStore_StoreContentChanged(object sender, StoreContentChangedEventArgs e) { // Bind to refreshed annotations store BindToAnnotations(_store.GetAnnotations()); }
批註綁定方法代碼:事件
private void BindToAnnotations(IList<Annotation> annotations) { // Bind to annotations in store annotationsListBox.DataContext = annotations; // Sort annotations by creation time var sortDescription = new SortDescription { PropertyName = "CreationTime", Direction = ListSortDirection.Descending }; var view = CollectionViewSource.GetDefaultView(annotationsListBox.DataContext); view.SortDescriptions.Clear(); view.SortDescriptions.Add(sortDescription); }
批註選擇時定位顯示批註錨定位置:
private void annotationsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { var comment = (sender as ListBox).SelectedItem as Annotation; if (comment != null) { // IAnchorInfo info; // service is an AnnotationService object // comment is an Annotation object _info = AnnotationHelper.GetAnchorInfo(_service, comment); var resolvedAnchor = _info.ResolvedAnchor as TextAnchor; var textPointer = (TextPointer) resolvedAnchor.BoundingStart; textPointer.Paragraph.BringIntoView(); } }
最後主窗口關閉時處理批註服務類的關閉:
private void MainWindow_Closed(object sender, EventArgs e) { if (_service != null && _service.IsEnabled) { _service.Disable(); _stream.Close(); } }