WPF FAQ - Annotations

Find answers for the most frequently asked questions
Expand All Collapse All

Users typically create annotations by first selecting some text or an item of interest and then right-clicking to display a context menu of annotation options.

The following example shows the XAML you can use to declare a Context Menu with routed commands that users can access to create and manage annotations.

[XAML]

<DocumentViewer.ContextMenu>
  <ContextMenu>
    <MenuItem Command='ApplicationCommands.Copy' />
    <Separator />
    <!-- Add a Highlight annotation to a user selection. -->
    <MenuItem Command='ann:AnnotationService.CreateHighlightCommand'
              Header='Add Highlight' />
    <!-- Add a Text Note annotation to a user selection. -->
    <MenuItem Command='ann:AnnotationService.CreateTextStickyNoteCommand'
              Header='Add Text Note' />
    <!-- Add an Ink Note annotation to a user selection. -->
    <MenuItem Command='ann:AnnotationService.CreateInkStickyNoteCommand'
              Header='Add Ink Note' />
    <Separator />
    <!-- Remove Highlights from a user selection. -->
    <MenuItem Command='ann:AnnotationService.ClearHighlightsCommand'
              Header='Remove Highlights' />
    <!-- Remove Text Notes and Ink Notes from a user selection. -->
    <MenuItem Command='ann:AnnotationService.DeleteStickyNotesCommand'
              Header='Remove Notes' />
    <!-- Remove Highlights, Text Notes, Ink Notes from a selection. -->
    <MenuItem Command='ann:AnnotationService.DeleteAnnotationsCommand'
              Header='Remove Highlights & Notes' />
  </ContextMenu>
</DocumentViewer.ContextMenu>

Permalink

You can match annotations with the corresponding annotated objects. For example, consider a simple document reader application that has a comments pane. The comments pane might be a listbox that displays the text from a list of annotations that are anchored to a document. If the user selects an item in the listbox, then the application brings into view the paragraph in the document that the corresponding annotation object is anchored to.

The following piece of C # code demonstrates how to implement the event handler of such a listbox that serves as the comments pane.

[C#]

void annotationsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{

    Annotation 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(this.service, comment);
        TextAnchor resolvedAnchor = info.ResolvedAnchor as TextAnchor;
        TextPointer textPointer = (TextPointer)resolvedAnchor.BoundingStart;
        textPointer.Paragraph.BringIntoView();
    }
} 
Permalink

The columns appear in the order in which their column styles were added to the tablestyle, being used by the grid. If you want to change this order, you need to create a new table style and add the column styles in the order you want things to appear.

Here are some code snippets that suggest how to do this.

[C#]

public void MoveColumn(DataGrid _dataGrid, string _mappingName, int fromCol, int toCol)
{
if(fromCol == toCol) return;
DataGridTableStyle oldTS = _dataGrid.TableStyles[_mappingName];
DataGridTableStyle newTS = new DataGridTableStyle();
newTS.MappingName = _mappingName;
for(int i = 0; i < oldTS.GridColumnStyles.Count; ++i)
{
if(i != fromCol && fromCol < toCol)
newTS.GridColumnStyles.Add(oldTS.GridColumnStyles[i]);
if(i == toCol)
newTS.GridColumnStyles.Add(oldTS.GridColumnStyles[fromCol]);
if(i != fromCol && fromCol > toCol)
newTS.GridColumnStyles.Add(oldTS.GridColumnStyles[i]);
}
_dataGrid.TableStyles.Remove(oldTS);
_dataGrid.TableStyles.Add(newTS);
}
Sample usage
private void button1_Click(object sender, System.EventArgs e)
{
MoveColumn( myDataGrid, 'Customers', 3, 1 );
}
Permalink

When the DataGridView needs to create a new cell in the column the method DataGridViewTextBoxCell.Clone is called in order to duplicate the ’DataGridViewColumn.CellTemplate’. It’s perfectly logical.

You can override the Clone method, but you can’t call base.Clone() since it returns an object of the base class type and you can’t code a copy constructor because there is no copy constructor for DataGridViewTextBoxCell.

With a base copy constructor you could code a Clone method like this :

[C#]

public override object Clone()
{
   return new MyDataGridViewEditingTextBoxCell(this);
}
With your overridden copy constructor you could code a Clone method like this :
public CustomDataGridViewTextBoxCell( CustomDataGridViewTextBoxCell cell)
  : base( cell )
{
   // Copy data of CustomDataGridViewTextBoxCell
   this.Flag = new Flag( cell.Flag );
   this.Data = cell.Data.Clone() as Data;
   // ...
}
Permalink

Share with

Couldn't find the FAQs you're looking for?

Please submit your question and answer.