Label control - Border lines issue on PDF export - wpf

I attempted to export a Label control with a white background and noticed some border lines in the output file. Is there a workaround for this problem?
UI As seen below:
Exported output
Xaml Code
<Canvas x:Name="sampleCanvas" Grid.Row="1" Grid.Column="0">
<Canvas>
<Grid x:Name="SimpleNode" Height="50" Width="50" Margin="200,200" Background="CornflowerBlue">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<Canvas>
<Border x:Name="Bd" BorderThickness="1"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Border BorderThickness="1" Margin="2">
<Grid Name="parent">
</Grid>
</Border>
</Border>
<Label x:Name="lbl" BorderBrush="Transparent" Background="#FFFF" BorderThickness="0"
Content="Node Text" FontSize="12" FontFamily="Calibri"
Canvas.Top="40"
Panel.ZIndex="2" HorizontalAlignment="Center">
</Label>
</Canvas>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</Grid>
</Canvas>
</Canvas>
Code Used for Printing
private void Button_Click(object sender, RoutedEventArgs e)
{
var filename = SaveCurrentDocument();
PrintDialog printDialog = new PrintDialog();
if ((bool)printDialog.ShowDialog())
{
PrintXPSDocument(printDialog, filename);
}
}
public string SaveCurrentDocument()
{
var filename = #"D:\exportWPF.xps";
File.Delete(filename);
using (Stream stream = File.Create(filename))
{
this.InvokeXps(stream);
}
return filename;
}
private void InvokeXps(Stream stream)
{
FixedDocument fixedDoc = new FixedDocument();
PageContent pageContent = new PageContent();
FixedPage fixedPage = CreateFixedPage(new Rect(0, 0, 500, 500));
((System.Windows.Markup.IAddChild)pageContent).AddChild(fixedPage);
fixedDoc.Pages.Add(pageContent);
Package package = Package.Open(stream, FileMode.Create, FileAccess.ReadWrite);
XpsDocument doc = new XpsDocument(package);
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
writer.Write(fixedDoc);
doc.Close();
package.Close();
}
internal FixedPage CreateFixedPage(Rect area)
{
VisualBrush visualBrush = new VisualBrush(sampleCanvas);
System.Windows.Shapes.Rectangle rect = new System.Windows.Shapes.Rectangle();
RenderOptions.SetBitmapScalingMode(visualBrush, BitmapScalingMode.HighQuality);
visualBrush.Stretch = Stretch.None;
visualBrush.ViewboxUnits = BrushMappingMode.Absolute;
visualBrush.Viewbox = area;
rect.Fill = visualBrush;
rect.Stretch = Stretch.Fill;
rect.Width = area.Width;
rect.Height = area.Height;
rect.Arrange(new Rect(area.Size));
FixedPage fp = new FixedPage();
fp.Width = area.Width;
fp.Height = area.Height;
fp.Children.Add(rect);
fp.Arrange(new Rect(area.Size));
return fp;
}
internal void PrintXPSDocument(PrintDialog printDialog, string filePath)
{
var document = new XpsDocument(filePath, FileAccess.Read);
var sequence = document.GetFixedDocumentSequence();
FixedDocument fixedDocument = sequence.References[0].GetDocument(false);
fixedDocument.DocumentPaginator.PageSize = new System.Windows.Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight);
printDialog.PrintDocument(fixedDocument.DocumentPaginator, "Printing");
document.Close();
}
I attempted to export my canvas control to.xps format and then print it using the Print Dialog via the shared code.

If you just want text then you should use a textblock rather than label.
Instead of
<Label x:Name="lbl" BorderBrush="Transparent" Background="#FFFF" BorderThickness="0"
Content="Node Text" FontSize="12" FontFamily="Calibri"
Canvas.Top="40"
Panel.ZIndex="2"
HorizontalAlignment="Center">
</Label>
You can use a textblock
<TextBlock x:Name="justText"
Background="#FFFF"
Text="Node Text"
FontSize="12"
FontFamily="Calibri"
Canvas.Top="40"
Panel.ZIndex="2"
TextAlignment="Center">
</TextBlock>
The functionality is very similar.
When you set content of a label to a string, a label creates a textblock as it's content and sets text to the string.
If you need the white background then you could try setting the height and width of the textblock but it seems you already have a white background anyhow.

Related

modal window turned blurry with no apparent reason

I can't figure out why, but my modal window turned blurry. Have no idea of what is causing this and it's frustrating me at this point. I did not notice this (which i suppose i would have) at any time when working on it, and suddenly i was like, what in the name of god is this...
What is suprising is that it only happens in the modal, and not in the main window, so it must be something i changed. I've already checked i don't have a blurry effect on just in case i activated it unintendedly, and can't figure out what else can be causing this. The only effect i applied was a dropShadow, as you can see in the images.
Here is a picture of what it's looking like:
blurry modal
The quality of the picture doesnt seem to be good enough, but you can see anyway how the modal is much more blurry than the background (which is the main window).
As you can see in this other picture, in the design window it's not showing blurry, just in case this might help.
not blurry in design window
any idea of what might have caused this? thx
EDIT: By the way, the content you see in the first image, which is not in the design window, is put there programatically.
<Window x:Class="CholaYTD.WpfMBFin"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:CholaYTD"
mc:Ignorable="d"
Title="WpfMBFin" Height="275" Width="400" ResizeMode="NoResize" ShowInTaskbar="False" WindowStartupLocation="CenterScreen" WindowStyle="None" Background="{x:Null}" Foreground="#FFEBF3FA" AllowsTransparency="True" SnapsToDevicePixels="True">
<Border BorderThickness="1" BorderBrush="#000000" CornerRadius="25" Background="#2F3138" VerticalAlignment="Center" HorizontalAlignment="Center" >
<Border.Effect>
<DropShadowEffect Opacity="0.8"/>
</Border.Effect>
<DockPanel MinWidth="375" MinHeight="100" Height="250" HorizontalAlignment="Center" VerticalAlignment="Top">
<StackPanel DockPanel.Dock="Top" HorizontalAlignment="Center" VerticalAlignment="Top" >
<!-- Titulo -->
<Label Content="DESCARGAS FINALIZADAS" HorizontalAlignment="Center" Margin="0 15 0 0" Foreground="#FFEBF3FA" FontFamily="Berlin Sans FB"
FontSize="20" />
<!-- Descripcion -->
<Label Content="Las descargas finalizaron con éxito." HorizontalAlignment="Center" Margin="0 5 0 0" Foreground="#FFEBF3FA"
FontFamily="Berlin Sans FB" FontSize="16" />
<!-- Descripcion fallidas -->
<!--<Label Content="Las descargas finalizaron con éxito." HorizontalAlignment="Center" Margin="0 0 0 0"
Foreground="#FFEBF3FA" FontFamily="Berlin Sans FB" FontSize="16" />-->
<!-- Enlaces -->
<TextBlock Name="textBox_enlaces" HorizontalAlignment="Center" Margin="0 0 0 0" Foreground="#FFEBF3FA" FontFamily="Berlin Sans FB" FontSize="16" >
</TextBlock>
</StackPanel>
<!-- Boton OK -->
<StackPanel Name="stackPanelCerrar" DockPanel.Dock="Bottom" Height="35" Width="60" VerticalAlignment="Bottom" Margin="0 0 0 10">
<Border Name="borderCerrar" BorderThickness="1" BorderBrush="#000000" CornerRadius="15" Background="#9FBED1" MouseDown="Border_MouseDown" MouseEnter="Border_MouseEnter" MouseLeave="Border_MouseLeave" Cursor="Hand" >
<Label Name="labelCerrar" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontFamily="Berlin Sans FB" FontSize="20" Foreground="#2F3138" >
OK
</Label>
</Border>
</StackPanel>
</DockPanel>
</Border>
public partial class WpfMBFin : Window
{
private List<string> listaEnlaces;
public WpfMBFin(List<string> failedList)
{
listaEnlaces = failedList;
InitializeComponent();
// declaramos la venata principal como padre de esta ventana
this.Owner = App.Current.MainWindow;
crearEnlaces();
}
private void crearEnlaces()
{
string youtubeURLStarting = "https://www.youtube.com/watch?v=";
string textoFinalEnlaces = "Sin embargo, ";
if (listaEnlaces.Count < 2)
{
textoFinalEnlaces += "el siguiente video no estaba disponible:\n";
Hyperlink hLink = new Hyperlink();
hLink.NavigateUri = new Uri(youtubeURLStarting + listaEnlaces.ElementAt(0));
hLink.RequestNavigate += new System.Windows.Navigation.RequestNavigateEventHandler(Hyperlink_RequestNavigate);
hLink.Inlines.Add(youtubeURLStarting + listaEnlaces.ElementAt(0));
textBox_enlaces.Inlines.Add(textoFinalEnlaces);
textBox_enlaces.Inlines.Add(hLink);
}
else
{
textoFinalEnlaces += "los siguientes videos no estaban disponibles:\n";
foreach (string link in listaEnlaces)
{
textoFinalEnlaces += "\n" + youtubeURLStarting + link;
}
}
}
// HANDLER de Hyperlinks
private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
System.Diagnostics.Process.Start(e.Uri.AbsoluteUri);
}
// EFECTO BOTON
private void Border_MouseDown(object sender, MouseButtonEventArgs e)
{
this.Close();
}
private void Border_MouseEnter(object sender, MouseEventArgs e)
{
stackPanelCerrar.Height = 36;
stackPanelCerrar.Width = 62;
borderCerrar.BorderBrush = (Brush)(new BrushConverter().ConvertFrom("#EBF3FA"));
borderCerrar.BorderThickness = (new Thickness(2, 2, 2, 2));
borderCerrar.Background = (Brush)(new BrushConverter().ConvertFrom("#EBF3FA"));
labelCerrar.Foreground = (Brush)(new BrushConverter().ConvertFrom("#2F3138"));
}
private void Border_MouseLeave(object sender, MouseEventArgs e)
{
stackPanelCerrar.Height = 35;
stackPanelCerrar.Width = 60;
borderCerrar.BorderBrush = Brushes.Black;
borderCerrar.BorderThickness = (new Thickness(1, 1, 1, 1));
borderCerrar.Background = (Brush)(new BrushConverter().ConvertFrom("#9FBED1"));
labelCerrar.Foreground = (Brush)(new BrushConverter().ConvertFrom("#2F3138"));
}
}

Binding all texts in TextBox from a html file - HtmlAgility

I have to make this app to show all texts from a html file, each text in his TextBox. so i did this ti'll now and i don't know how to continue:
.xaml.cs
public MainWindow()
{
InitializeComponent();
}
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
private void Button_Click_1(object sender, RoutedEventArgs e)
{
OpenFileDialog open = new OpenFileDialog();
open.Filter = "HTM | *.htm";
if (open.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
doc.Load(open.OpenFile());
var listItems = doc.DocumentNode.SelectSingleNode("//ul").SelectNodes("li");
var src = new List<string>();
foreach (var li in listItems)
{
src.AddRange(li.Descendants("p").Select(x => x.InnerText));
}
myListBox.ItemsSource = src;
}
.xaml
<Grid>
<Button Content="Open" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
<ListBox Name="myListBox" HorizontalAlignment="Left" Height="249" Margin="10,48,0,0" VerticalAlignment="Top" Width="497">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Height="23" TextWrapping="Wrap" Width="400" Text="{Binding Description}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Oh I think I see your problem... you're trying to data bind to a property named Description in your XAML. Would you like to show me where that property was declared, because I can't see one. Furthermore, your ListBox.ItemsSource is set to a List<string>, so there can't be any Description property to bind to. Instead, try this:
<TextBox Height="23" TextWrapping="Wrap" Width="400" Text="{Binding}" />

Animate control with respecting parents/container

I have a control that I move with help of animation from the bottom to the final position. My problem is now that I want to change the behaviour of the animation, so that it respects the outer container (DarkGray).
The orange Ractangle should only be visible on the white background and not on the darkgray Grid!
Code:
MainWindow.xaml:
<Grid Background="DarkGray">
<Grid Margin="50"
Background="White">
<Rectangle x:Name="objectToMove"
VerticalAlignment="Bottom"
Fill="Orange"
Height="50"
Width="50"/>
<Button Height="20"
Width="40"
Margin="20"
Content="Move"
Click="Button_Click"
VerticalAlignment="Top"/>
</Grid>
</Grid>
MainWindow.xaml.cs:
private void Button_Click(object sender, RoutedEventArgs e)
{
var target = objectToMove;
var heightOfControl = target.ActualHeight;
var trans = new TranslateTransform();
target.RenderTransform = trans;
var myAnimation = new DoubleAnimation(heightOfControl, 0, TimeSpan.FromMilliseconds(600));
trans.BeginAnimation(TranslateTransform.YProperty, myAnimation);
}
Current:
Desired solution:
Use ClipToBounds Property for this.
<Grid Margin="50"
Background="White"
ClipToBounds="True">

Canvas print - wpf

I used these code in order to print out the UI. Printing out is working, but if the size of paper is over, the UI cuts off in the middle of a canvas.
Is there any possible way not to be cut off in the middle?
<--cs code-->
PrintDialog dialog = new PrintDialog();
dialog.PrintVisual(lst , "print");
<--Xaml -->
<ListView Name="lst">
<Grid Name="grdPrint">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Canvas Grid.Row="0" >
.......
</Canvas>
<HListBox x:Name="lstImage" ItemsSource="{Binding IMG, Mode=TwoWay}" Grid.Row="1" IsHitTestVisible="True">
<HListBox.ItemTemplate>
<DataTemplate>
<HImage Margin="0" Width="590" Height="590" Stretch="Fill" Source="{Binding IMG_PATH_NM, Converter={StaticResource StrUriConverter}}" Tag="{Binding IMG_PATH_NM}">
</HImage>
</DataTemplate>
</HListBox.ItemTemplate>
<HListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" IsHitTestVisible="True"/>
</ItemsPanelTemplate>
</HListBox.ItemsPanel>
</HListBox>
</Grid>
</ListView>
This method will print the canvas to PNG file.
public void ExportToPNG(string imgpath, Canvas surface)
{
Uri path = new Uri(imgpath);
if (path == null)
return;
Transform transform = surface.LayoutTransform;
surface.LayoutTransform = null;
Size size = new Size(surface.Width, surface.Height);
surface.Measure(size);
surface.Arrange(new Rect(size));
RenderTargetBitmap renderBitmap =
new RenderTargetBitmap(
(int)size.Width,
(int)size.Height,
96d,
96d,
PixelFormats.Pbgra32);
renderBitmap.Render(surface);
using (FileStream outStream = new FileStream(path.LocalPath, FileMode.Create))
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
encoder.Save(outStream);
}
surface.LayoutTransform = transform;
}
You could create an BitmapImage (see RenderTargetBitmap to create a bitmap from an element). This bitmap can then be saved as a JPEG file and manipulated using GDI+ (System.Image).

How to access Button programatically if the button is inside using C#

I have few questions as I am usign XAML for the first time.
How do I use the button (BrowseButton) to browse a folder in Harddrive ?
In this case as the button is inside
Can I use the way I have shown below?
Actually first dockpanel will hold the image and some label and the other dockpanel will have tabcontrol in it.
If I have a tabcontrol, How can I add a listview which can increase the tabs during runtime.. and the listview should be available in the runtime also.
How to add a close("X") mark on the top of the tab to close the button
probably I asked a lot of questions, sorry :(
Please help
<Grid>
<DockPanel>
<StackPanel>
<Image Name="imgClientPhoto" HorizontalAlignment="Left" VerticalAlignment="Top" Width="auto" Height="auto" Grid.Column="0" Grid.Row="0" Margin="0"
Source="D:ehtmp_top_left.gif" MinWidth="450" MinHeight="100" Grid.IsSharedSizeScope="True">
</Image>
<Button x:Name="BrowseButton" Margin="0,13.638,30,14.362" Content="Browse" Click="BrowseButton_Click" HorizontalAlignment="Right" Width="111" />
<TextBox x:Name="txtBxBrowseTB" Margin="46,10,146,10" Text="TextBox" TextWrapping="Wrap" TextChanged="BrowseTB_TextChanged"></TextBox>
<Label HorizontalAlignment="Left" Margin="-14,22,0,10" Name="label1" Width="69.75" FontSize="13" VerticalContentAlignment="Top" HorizontalContentAlignment="Center">Path:</Label>
</Grid>
</GroupBox>
</Grid>
</StackPanel>
</DockPanel>
<DockPanel>
<StackPanel Margin="0,158,0,0" HorizontalAlignment="Left" Width="330" Height="557.5" VerticalAlignment="Top">
<TextBox Height="50" Name="textBox1" Width="240" Margin="0,35,0,0" VerticalAlignment="Stretch" HorizontalAlignment="Right" />
<ListBox Height="470" Name="listBox1" Width="332" Background="LightGray" Margin="0,0,0,0" BorderBrush="IndianRed" BorderThickness="3" />
</StackPanel>
<TabControl Height="234" Name="tabControl1" Width="1035" Margin="0,0,0,0">
<TabItem Header="tabItem1" Name="tabItem1">
<Grid Height="144" />
</TabItem>
</TabControl>
</DockPanel>
</Grid>
1) The browse code should be something like this:
private void BrowseButton_Click(object sender, RoutedEventArgs e)
{
System.Windows.Forms.FolderBrowserDialog browse = new System.Windows.Forms.FolderBrowserDialog();
browse.RootFolder= Environment.SpecialFolder.MyDocuments;
browse.SelectedPath = "C:\\InitalFolder\\SomeFolder";
if (browse.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
txtBxBrowseTB.Text = browse.SelectedPath;
}
}
2) I have tried to simplify the xaml. Does this look like something you could go with?:
<Grid>
<Image Name="imgClientPhoto" Margin="0" Height="262" VerticalAlignment="Top" HorizontalAlignment="Left" ></Image>
<StackPanel VerticalAlignment="Stretch" >
<StackPanel VerticalAlignment="Top" Orientation="Horizontal" Height="30">
<Button Name="BrowseButton" Content="Browse" Click="BrowseButton_Click" HorizontalAlignment="Right" Width="111" />
<Label Name="label1" Width="69.75" FontSize="13" VerticalContentAlignment="Center" HorizontalContentAlignment="Right">Path:</Label>
<TextBox Name="txtBxBrowseTB" Width="200" Text="TextBox" VerticalContentAlignment="Center" TextWrapping="Wrap" TextChanged="BrowseTB_TextChanged"></TextBox>
</StackPanel>
<StackPanel>
<StackPanel Orientation="Vertical">
<TextBox Height="50" Name="textBox1" />
<ListBox Height="470" Name="listBox1" Background="LightGray" Margin="0,0,0,0" BorderBrush="IndianRed" BorderThickness="3" MouseLeftButtonUp="listBox1_MouseLeftButtonUp">
<ListBoxItem>User1</ListBoxItem>
<ListBoxItem>User2</ListBoxItem>
<ListBoxItem>User3</ListBoxItem>
<ListBoxItem>User4</ListBoxItem>
</ListBox>
</StackPanel>
<TabControl Name="tabControl1" />
</StackPanel>
</StackPanel>
</Grid>
You can also have a close button in the tab item Header. As many of the content properties in xaml controls, the content can actually be controls, and not necessary just a text.
<TabControl Name="tabControl1" >
<TabItem Name="tabItem1" >
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Label>TabHeader1</Label>
<Button Height="20" Width="20" FontWeight="Bold" Click="CloseTabButton_Click">X</Button>
</StackPanel>
</TabItem.Header>
<Grid Height="144">
<ListView />
</Grid>
</TabItem>
</TabControl>
3) Here is how you would add the tabs in C# dynamically:
private void listBox1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
//Get selected item
ListBoxItem item = (ListBoxItem)listBox1.SelectedItem;
string itemText = item.Content.ToString();
//Check if item is already added
foreach (TabItem tItem in tabControl1.Items)
{
if ((string)tItem.Tag == itemText)
{
//Item already added, just activate the tab
tabControl1.SelectedItem = tItem;
return;
}
}
//Build new tab item
TabItem tabItem = new TabItem();
tabItem.Tag = itemText;
//First build the Header content
Label label = new Label();
Button button = new Button();
label.Content = itemText;
button.Content = "X";
button.Height = 20;
button.Width = 20;
button.FontWeight = FontWeights.Bold;
button.Click += CloseTabButton_Click; //Attach the event click method
button.Tag = tabItem; //Reference to the tab item to close in CloseTabButton_Click
StackPanel panel = new StackPanel();
panel.Orientation = Orientation.Horizontal;
panel.Children.Add(label);
panel.Children.Add(button);
tabItem.Header = panel;
//Then build the actual tab content
//If you need only the ListView in here, you don't need a grid
ListView listView = new ListView();
//TODO: Populate the listView with what you need
tabItem.Content = listView;
//Add the finished tabItem to your TabControl
tabControl1.Items.Add(tabItem);
tabControl1.SelectedItem = tabItem; //Activate the tab
}
private void CloseTabButton_Click(object sender, RoutedEventArgs e)
{
//The tab item was set to button.Tag when it was added
Button button = (Button)sender;
TabItem tabItem = (TabItem)button.Tag;
if (tabItem != null)
{
button.Click -= CloseTabButton_Click; //Detach event handler to prevent memory leak
tabControl1.Items.Remove(tabItem);
}
}

Resources