InkPresenter Sample Code

,

The sample for this section is a simple sketch page that allows the user to draw a picture, undo and redo sketch lines, and clear the page using an application bar menu item (see Figure 7.4). The code presented in this section elaborates on the previous example and takes a more MVVM-centric approach.

Image

FIGURE 7.4 InkPresenter sample app.

The code for this sample is located in the InkPresenterView page and the InkPresenterViewModel class in the downloadable sample code.

An InkPresenter in the view is bound to the viewmodel’s StrokeCollection. As the user interacts with the view, viewmodel commands populate the StrokeCollection with Stroke objects.

Each command is instantiated in the viewmodel’s constructor. When executed, the beginStrokeCommand creates a new Stroke representing the beginning of a line drawn by the user. As the user moves a finger across the InkPresenter, the setStrokePointCommand is executed, which adds a new StylusPoint to the list of points for the current Stroke. Finally, when the user takes his finger off the display, the endStrokeCommand is executed setting the current Stroke to null (see Listing 7.2).

The viewmodel maintains a Stack of Strokes, called undoneStrokes, which contains strokes that have been undone by the user. The undoCommand pushes the last Stroke in the StrokeCollection onto undoneStrokes and then removes it from the StrokesCollection. Conversely, the redoCommand pops the top Stroke from undoneStrokes and places it back in the StrokesCollection.

LISTING 7.2. InkPresenterViewModel Class (excerpt)


public InkPresenterViewModel() : base("InkPresenter")
{
    beginStrokeCommand = new DelegateCommand<Point>(
        point =>
            {
                stroke = new Stroke();
                stroke.StylusPoints.Add(ConvertToStylusPoint(point));
                stroke.DrawingAttributes.Color = stylusColor;
                strokes.Add(stroke);
            });

    setStrokePointCommand = new DelegateCommand<Point>(
        point =>
            {
                if (stroke != null)
                {
                    stroke.StylusPoints.Add(ConvertToStylusPoint(point));
                }
            });
    endStrokeCommand = new DelegateCommand(obj => stroke = null);

    clearCommand = new DelegateCommand(obj => strokes.Clear());

    undoCommand = new DelegateCommand(
        delegate
            {
                if (strokes.Count > 0)
                {
                    undoneStrokes.Push(strokes.Last());
                    strokes.RemoveAt(strokes.Count - 1);
                }
            });

    redoCommand = new DelegateCommand(
        delegate
            {
                if (undoneStrokes.Count > 0)
                {
                    strokes.Add(undoneStrokes.Pop());
                }
            });
}


The BeginStrokeCommand, SetStrokePointCommand, and EndStrokeCommand are executed when the InkPresenters element’s MouseLeftButtonDown, MouseMove, and MouseLeftButtonUp events are raised, respectively (see Listing 7.3).

LISTING 7.3. InkPresenterView Class


public partial class InkPresenterView : PhoneApplicationPage
{
    public InkPresenterView()
    {
        InitializeComponent();
        DataContext = new InkPresenterViewModel();
    }

    InkPresenterViewModel ViewModel
    {
        get
        {
            return (InkPresenterViewModel)DataContext;
        }
    }
    void InkPresenter_MouseMove(object sender, MouseEventArgs e)
    {
        InkPresenter inkPresenter = (InkPresenter)sender;
        ViewModel.SetStrokePointCommand.Execute(e.GetPosition(inkPresenter));
    }

    void InkPresenter_MouseLeftButtonDown(
            object sender, MouseButtonEventArgs e)
    {
        InkPresenter inkPresenter = (InkPresenter)sender;
        ViewModel.BeginStrokeCommand.Execute(e.GetPosition(inkPresenter));
    }

    void InkPresenter_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        ViewModel.EndStrokeCommand.Execute(null);
    }
}


The three commands UndoCommand, RedoCommand, and ClearCommand are executed via the custom ApplicationBar wrapper, named AppBar, in the view. The AppBar is discussed further in Chapter 8, “Taming the Application Bar.”

<u:AppBar IsEnabled="True" IsVisible="True" IsMenuEnabled="True">
    <u:AppBarIconButton
        Command="{Binding UndoCommand}"
        Text="Undo"
        IconUri="/ControlExamples/Images/AppBarArrowUndo.png" />
    <u:AppBarIconButton
        Command="{Binding RedoCommand}"
        Text="Redo"
        IconUri="/ControlExamples/Images/AppBarArrowRedo.png" />
    <u:AppBar.MenuItems>
        <u:AppBarMenuItem
            Command="{Binding ClearCommand}"
            Text="Clear" />
        </u:AppBar.MenuItems>
</u:AppBar>

When the Undo or Redo buttons are pressed, the associated viewmodel command is executed. In addition, when the user taps the Clear button in the application bar menu the ClearCommand is executed, removing all items from the StrokeCollection in the viewmodel.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.134.232