Sunday, October 31, 2010

Animated sine wave addition

My son is studying physics at school and one of topics was "waves". The physics study book he is using is printed and so doesn't include any wave animations. I thought animations would help with understanding but couldn't find any on-line animation where the user could change the wave frequency, phase.

I've wrote a WPF application where the user could control the frequency, phase of two sine wave and see the result of adding these two wave together. I then ported this to silverlight (which required a few small changes to the code) and published the result on www.nzdev.com

Since then, I've added the ability to also change the wave amplitude.

Sunday, October 24, 2010

WPF DocumentViewer

The WPF DocumentViewer control has some annoying features.

1. A find control ("Type text to find") that doesn't work.
2. A print function with limited configuration.

I work around these features by subclassing the DocumentViewer as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows;
using System.Printing;
using System.Windows.Xps;

namespace FixedDocPrinting
{
public class PrintDocumentViewer : DocumentViewer
{
PageOrientation _pageOrientation = PageOrientation.Portrait;
public PageOrientation PageOrientation
{
get { return _pageOrientation; }
set { _pageOrientation = value; }
}

Visibility _findControlVisibility = Visibility.Collapsed;
public Visibility FindControlVisibility
{
get
{
return _findControlVisibility;
}
set
{
_findControlVisibility = value;
UpdateFindControlVisibility();
}
}

private void UpdateFindControlVisibility()
{
object toolbar = this.Template.FindName("PART_FindToolBarHost", this);
ContentControl cc = toolbar as ContentControl;
if (cc != null)
{
HeaderedItemsControl itemsControl = cc.Content as HeaderedItemsControl;
if (itemsControl != null)
itemsControl.Visibility = FindControlVisibility;
}
}

public PrintDocumentViewer()
{
Loaded += new RoutedEventHandler(PrintDocumentViewer_Loaded);
}

void PrintDocumentViewer_Loaded(object sender, RoutedEventArgs e)
{
UpdateFindControlVisibility();
}

protected override void OnPrintCommand()
{
PrintDialog printDialog = new PrintDialog();
printDialog.PrintQueue = LocalPrintServer.GetDefaultPrintQueue();
printDialog.PrintTicket = printDialog.PrintQueue.DefaultPrintTicket;

printDialog.PrintTicket.PageOrientation = PageOrientation;

if (printDialog.ShowDialog() == true)
{
// Code assumes this.Document will either by a FixedDocument or a FixedDocumentSequence
FixedDocument fixedDocument = this.Document as FixedDocument;
FixedDocumentSequence fixedDocumentSequence = this.Document as FixedDocumentSequence;

if (fixedDocument != null)
fixedDocument.PrintTicket = printDialog.PrintTicket;

if (fixedDocumentSequence!= null)
fixedDocumentSequence.PrintTicket = printDialog.PrintTicket;

XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(printDialog.PrintQueue);

if (fixedDocument != null)
writer.WriteAsync(fixedDocument, printDialog.PrintTicket);

if (fixedDocumentSequence != null)
writer.WriteAsync(fixedDocumentSequence, printDialog.PrintTicket);
}
}
}
}

This hides the find control and gives me the ability to print in Landscape.

To use this code, you will need to add a reference to the ReachFramework dll which contains useful classes in the System.Printing and System.Windows.Xps name spaces.