What you want to do is use the VisualBrush class built into WPF. This should provide the functionality I think you're looking for.
VisualBrush class on MSDN
Cheers.
EDIT: Expanded answer for expanded question
This code snippet should put you in the right direction for saving the image to a file.
Stefan Wick's blog - Rendering ink and image to a bitmap using WPF
// render InkCanvas' visual tree to the RenderTargetBitmap
RenderTargetBitmap targetBitmap =
new RenderTargetBitmap((int)inkCanvas1.ActualWidth,
(int)inkCanvas1.ActualHeight,
96d, 96d,
PixelFormats.Default);
targetBitmap.Render(inkCanvas1);
// add the RenderTargetBitmap to a Bitmapencoder
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(targetBitmap));
// save file to disk
FileStream fs = File.Open(fileName, FileMode.OpenOrCreate);
encoder.Save(fs);
EDIT: More code to try and demonstrate possible solution
The XAML:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="UsingVisualBrush.PaintingWithVisuals" >
<StackPanel Name="MyStackPanel"
Orientation="Horizontal"
Margin="10" Background="White"
HorizontalAlignment="Left" >
<Rectangle Name="myRect" Width="150" Height="150"
Stroke="Black" Margin="0,0,5,0" Loaded="UserControl_Loaded" >
</Rectangle>
</StackPanel>
</Page>
Now the code behind...
namespace UsingVisualBrush
{
public partial class PaintingWithVisuals : Page
{
public PaintingWithVisuals()
{
}
private void UserControl_Loaded(object sender, RoutedEventArgs args)
{
Uri resourceLocater = new Uri("/component/Users.xaml", UriKind.Relative);
var obj = Application.LoadComponent(resourceLocater);
// Using UserControl-derived class
var mylocatedControl = obj as UserControl;
mylocatedControl.Background = Brushes.Blue;
mylocatedControl.Width = 20;
mylocatedControl.Height = 20;
// Using UserControl-derived class
var myControl = new UserControl();
myControl.Background = Brushes.Blue;
myControl.Width = 20;
myControl.Height = 20;
// using UIElement-derived class
var myVisualBrush = new VisualBrush();
var panel = new StackPanel { Background = Brushes.Transparent };
// panel.Children.Add(new TextBlock { Background = Brushes.Green, Foreground = Brushes.Black, FontSize = 10, Margin = new Thickness(10), Text = "Hello World from Dave" });
// panel.Children.Add(myControl);
panel.Children.Add((UserControl)obj);
myVisualBrush.Visual = panel;
((UserControl)obj).Background = Brushes.Blue;
myRect.Fill = myVisualBrush;
}
}
}
I hope this gets you a bit closer...