I've implemented this solution and it worked for me:
Can multiple xps documents be merged to one in WPF?
My problem is that the pages I want to merge are in landscape orientation. When the ContainerVisual is added it creates by default a page in vertical orientation. How can I change the orientation to ContainerVisual?
private void AddXPSDocument(string sourceDocument, SerializerWriterCollator vxpsd)
{
XpsDocument xpsOld = new XpsDocument(sourceDocument, FileAccess.Read);
FixedDocumentSequence seqOld = xpsOld.GetFixedDocumentSequence();
foreach (DocumentReference r in seqOld.References)
{
FixedDocument d = r.GetDocument(false);
foreach (PageContent pc in d.Pages)
{
FixedPage fixedPage = pc.GetPageRoot(false);
double width = fixedPage.Width;
double height = fixedPage.Height;
Size sz = new Size(width, height);
fixedPage.Width = width;
fixedPage.Height = height;
fixedPage.Measure(sz);
fixedPage.Arrange(new Rect(new Point(), sz));
//fixedPage.UpdateLayout();
ContainerVisual newPage = new ContainerVisual();
newPage.Children.Add(fixedPage);
vxpsd.Write(newPage);
}
}
xpsOld.Close();
}
You need to add a RotateTransform to the page visual.
Visual originalPage = Paginator.GetPage(pageNumber).Visual;
var pageContentVisual = new ContainerVisual();
TransformGroup group = new TransformGroup();
group.Children.Add(new RotateTransform { Angle = 90.0 });
pageContentVisual.Transform = group;
pageContentVisual.Children.Add(originalPage);
Note: The above was copied from a custom DocumentPaginator however you should be able to apply it your situation.
Related
On WPF I am creating a menu item dynamically at run time.
I set the icon from a StreamGeometry that's stored on a ResourceDictionary. Everything works OK but: how do I set the size of the icon?
MenuItem menExit = new MenuItem();
menExit.Header = "Exit"; // will be changedlater
menExit.Command = UICommands.CmdExit;
menExit.CommandBindings.Add(new CommandBinding(UICommands.CmdExit, CmdExitExecute, CmdExitCanExecute));
menExit.Icon = (StreamGeometry)FindResource("ImgExit");
//SET THE SIZE HERE????????
// Eventually, how do I set the fill color?
menu.Items.Add(menExit);
Note, I am doing all this at run time and not in xalm
I suggest you to create a path on which you can specify Height, Width and Fill and set your StreamGeometry as the Data of the path. Then put this Path as the icon of the MenuItem.
var path = new Path
{
Height = 20,
Width = 20,
Fill = new SolidColorBrush(Colors.Blue),
Data = (StreamGeometry) FindResource("ImgExit")
};
menExit.Icon = path;
You can always try this:
/// <summary>
/// Convert Geometry to ImageSource, Draws the Geometry on a bitmap surface and centers it.
/// </summary>
/// <param name="geometry"></param>
/// <param name="TargetSize"></param>
/// <returns></returns>
ImageSource Geometry_To_ImageSource(Geometry geometry, int TargetSize)
{
var rect = geometry.GetRenderBounds(new Pen(Brushes.Black, 0));
var bigger = rect.Width > rect.Height ? rect.Width : rect.Height;
var scale = TargetSize / bigger;
Geometry scaledGeometry = Geometry.Combine(geometry, geometry, GeometryCombineMode.Intersect, new ScaleTransform(scale, scale));
rect = scaledGeometry.GetRenderBounds(new Pen(Brushes.Black, 0));
Geometry transformedGeometry = Geometry.Combine(scaledGeometry, scaledGeometry, GeometryCombineMode.Intersect, new TranslateTransform(((TargetSize - rect.Width) / 2) - rect.Left, ((TargetSize - rect.Height) / 2) - rect.Top));
RenderTargetBitmap bmp = new RenderTargetBitmap(TargetSize, TargetSize, 96, 96, PixelFormats.Pbgra32);
DrawingVisual viz = new DrawingVisual();
using (DrawingContext dc = viz.RenderOpen())
{
dc.DrawGeometry(Brushes.Black, null, transformedGeometry);
}
bmp.Render(viz);
var mem = new MemoryStream();
PngBitmapEncoder pngEncoder = new PngBitmapEncoder();
pngEncoder.Frames.Add(BitmapFrame.Create(bmp));
pngEncoder.Save(mem);
var itm = GetImg(mem);
return itm;
}
BitmapImage GetImg(MemoryStream ms)
{
var bmp = new BitmapImage();
bmp.BeginInit();
bmp.StreamSource = ms;
bmp.EndInit();
return bmp;
}
Is it possible to design a pdf using HTML and js in a WPF application(C#). I tried using iTextSharp by taking a image of the control i want to export and then pasted in the pdf. It worked, but the problem is the control has to be visible. So, lets say if there is a listview in that control and that listview doesn't fits in one window, then whole listview doesn't gets exported. Any ideas how to approach?
This is so far I've done for exporting ListView to pdf.
ListView item = list;
double width = item.ActualWidth;
double height = item.ActualHeight;
Document doc = new Document(new iTextSharp.text.Rectangle(1200f, 700f));
String filePath;
string path = Environment.CurrentDirectory + "\\export\\" ;
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
filePath = path + "\\Test_.pdf";
PdfWriter.GetInstance(doc, new FileStream(filePath, FileMode.Append));
doc.Open();
RenderTargetBitmap bmpCopied = new RenderTargetBitmap((int)Math.Round(width + 100), (int)Math.Round(height + 50), 0, 0, PixelFormats.Default);
DrawingVisual drawingVisual = new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
item.Background = Brushes.White;
VisualBrush visualBrush = new VisualBrush(item);
drawingContext.DrawRectangle(Brushes.White, null, new Rect(new Point(), new Size(width + 100, height + 50)));
drawingContext.DrawRectangle(visualBrush, null, new Rect(new Point(), new Size(width + 100, height + 50)));
}
bmpCopied.Render(drawingVisual);
item.Background = Brushes.Transparent;
byte[] data;
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmpCopied));
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
data = ms.ToArray();
}
iTextSharp.text.Image pdfImage = iTextSharp.text.Image.GetInstance(data);
doc.Add(pdfImage);
doc.Close();
The pdf gets created, but opening the pdf shows error. Secondly, my ListView is scrollable, will all the items be shown in the pdf?. I just need to get it working. Any way would be ok for me
I have Image and i have created visual brush for image when i move object form one point to another. but I don't see image on visual brush. if you see my rectangle, it suppose to show image.
See image : http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/e8833983-3d73-45e1-8af1-3bc27846441d
here is code:
internal static VisualBrush GetVisualBrushByObject(LabelObject obj, Rect objectRect, int quality, FlowDirection flowdirection)
{
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
Rect objectbounds = new Rect(0, 0, objectRect.Width, objectRect.Height);
if (obj is TextObject)
{
TextObject txtObj = obj.Clone() as TextObject;
DymoTextBlock txtBlock = txtObj.DymoTextBlock as DymoTextBlock;
objectbounds = new Rect(txtBlock.GetNaturalSize(txtBlock.GetFormattedText(flowdirection)));
}
if (obj is ImageObject)
{
drawingContext.DrawImage(((ImageObject)obj).Image, objectbounds);
}
LabelObject.RenderParams lrp = new LabelObject.RenderParams(drawingContext, new Common.Resolution(96, 96), false, objectbounds, flowdirection);
obj.Render(lrp);
VisualBrush vBrush = new VisualBrush();
vBrush.TileMode = TileMode.None;
vBrush.Stretch = Stretch.Fill;
if (obj is ImageObject)
{
vBrush.Opacity = 0.4;
}
drawingContext.Close();
vBrush.Visual = drawingVisual;
return vBrush;
}
pls help me
Thanks
If you are moving your image with Transforms(TranslateTransform), then you have to undo it for the visual brush phase.
I've got an app that turns some XAML Usercontrols into PNGs - this has worked really well up to now, unfortunately I now need to double the size of the images.
My method (that doesn't work!) was to add a ScaleTransform to the visual element after I've loaded it ...
This line is the new line at the top of the SaveUsingEncoder method.
visual.RenderTransform = GetScaleTransform(2);
The PNG is the new size (3000 x 2000) - but the XAML is Rendered at 1500x1000 in the centre of the image.
Can anyone assist please?
private void Load(string filename)
{
var stream = new FileStream(filename), FileMode.Open);
var frameworkElement = (FrameworkElement)(XamlReader.Load(stream));
var scale = 2;
var encoder = new PngBitmapEncoder();
var availableSize = new Size(1500 * scale, 1000 * scale);
frameworkElement.Measure(availableSize);
frameworkElement.Arrange(new Rect(availableSize));
name = name.Replace(" ", "-");
SaveUsingEncoder(frameworkElement, string.Format(#"{0}.png", name), encoder, availableSize);
}
private TransformGroup GetScaleTransform(int scale)
{
var myScaleTransform = new ScaleTransform {ScaleY = scale, ScaleX = scale};
var myTransformGroup = new TransformGroup();
myTransformGroup.Children.Add(myScaleTransform);
return myTransformGroup;
}
private void SaveUsingEncoder(FrameworkElement visual, string fileName, BitmapEncoder encoder, Size size)
{
visual.RenderTransform = GetScaleTransform(2);
var bitmap = new RenderTargetBitmap(
(int) size.Width,
(int) size.Height,
96,
96,
PixelFormats.Pbgra32);
bitmap.Render(visual);
var frame = BitmapFrame.Create(bitmap);
encoder.Frames.Add(frame);
using (var stream = File.Create(fileName))
{
encoder.Save(stream);
}
}
Called visual.UpdateLayout before rendering into the RenderTargetBitmap
(Thanks to Clemens for this answer - but he put it as a comment!)
I have added the images dynamtically from a url to panorama item. I need the width to be 800 which the image should be in the next item space also. For that in my previous application I have set the orientation to horizontal in Xaml. But no i need to set in code but i cant is there any way to do that.
private void AddItem(string uri, string header)
{
var panoramaItem = new PanoramaItem();
panoramaItem.Width = 800;
panoramaItem.Height = 550;
panoramaItem.Header = "";
var grid = new Grid();
var image = new Image();
image.Source = new BitmapImage(new Uri(uri, UriKind.RelativeOrAbsolute));
panoramaItem.Content = image;
pan.Items.Add(panoramaItem);
}
PanoramaItem has an Orientation property for handling scrolling direction. It takes value of System.Windows.Controls.Orientation enum in System.Windows assembly. Your code should looks like:
using System.Windows.Controls;
And orientation assigment:
panoramaItem.Orientation = Orientation.Horizontal;