WPF print canvas with children instead of window - c#

I want to write a WPF program wherein I want to print a specific part of the program/window. I only want the canvas to be printed.
Unfortunately the whole window gets printed all the time, but I only want the canvas to be printed.
Here is an example of the layout:
Here is my code:
public partial class MainWindow : Window
{
string name;
public MainWindow()
{
InitializeComponent();
}
private void Text(double x, double y, string text)
{
canvasPrintExample.Children.Clear();
TextBlock textBlock = new TextBlock();
textBlock.Text = text;
textBlock.Foreground = new SolidColorBrush(Colors.Black);
Canvas.SetLeft(textBlock, x);
Canvas.SetTop(textBlock, y);
canvasPrintExample.Children.Add(textBlock);
}
private void tbxClientInfoName_TextChanged(object sender, TextChangedEventArgs e)
{
clientInfoName = tbxClientInfoName.Text;
Text(0, 0, name);
}
private void btnPrintCanvas_Click(object sender, RoutedEventArgs e)
{
PrintDialog prnt = new PrintDialog();
if (prnt.ShowDialog() == true)
{
Size pageSize = new Size(prnt.PrintableAreaWidth, prnt.PrintableAreaHeight);
canvasPrintExample.Measure(pageSize);
canvasPrintExample.Arrange(new Rect(0, 0, pageSize.Width, pageSize.Height));
prnt.PrintVisual(canvasPrintExample, "Print");
}
this.Close();
}
}
I've tried changing this line in 'btnPrintCanvas_Click'
Size pageSize = new Size(canvasPrintExample.Width, canvasPrintExample.Height);
And I've tried hardcode the size:
Size pageSize = new Size(200, 400);
But nothing changes. All I get is this .pdf print:
Edit - added .xaml
<Window x:Class="Test.MainWindow"
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:Factv001"
mc:Ignorable="d"
Title="MainWindow" Height="810" Width="1010" Background="LightGray">
<Grid>
<Canvas Name="canvasPrintExample" HorizontalAlignment="Left" Height="750" Margin="452,10,0,0" VerticalAlignment="Top" Width="530.3" Background="White"/>
<TextBox Name="tbxClientInfoName" HorizontalAlignment="Left" Height="23" Margin="10,31,0,0" TextWrapping="Wrap" Text="Name" VerticalAlignment="Top" Width="225" TextChanged="tbxClientInfoName_TextChanged"/>
<Button x:Name="btnPrintCanvas" Content="Print" HorizontalAlignment="Left" Margin="167,682,0,0" VerticalAlignment="Top" Width="75" Click="btnPrintCanvas_Click"/>
</Grid>

Related

PreviewLeftButtonUp fires too late

I'm making a simple program, where I can drag and drop elements to the grid, but their position depends on the particular column and row. So I tried to use PreviewLeftButtonUp event to find out the position, that is pointed with cursor, but it fires after Drop event and elements are placed in the wrong position.
XAML:
<Window x:Class="Pazzles.MainWindow"
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:Pazzles"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Menu x:Name="menu" VerticalAlignment="Top" Grid.Row="0">
<MenuItem Header="Розбити зображення">
<MenuItem Header="Відкрити" Click="OpenImage_Click"/>
<MenuItem Header="Розрізати зображення" Click="CutImage_Click"/>
</MenuItem>
<MenuItem Header="Зібрати пазл" Click ="OpenCatalog_Click">
</MenuItem>
</Menu>
<Grid Grid.Row="1" Name="layout">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollViewer>
<StackPanel x:Name="stackPanel" Width="150" Grid.Column="0"/>
</ScrollViewer>
<GridSplitter Grid.Column="1" ShowsPreview="False" Width="3" VerticalAlignment="Stretch" HorizontalAlignment="Center"/>
<Grid x:Name="grid" Background="Transparent" Grid.Column="2" ShowGridLines="True" AllowDrop="True" PreviewMouseLeftButtonUp="grid_MouseMove" Drop ="grid_Drop">
</Grid>
</Grid>
</Grid>
</Window>
C# :
private void img_MouseDown(object sender, MouseButtonEventArgs e)
{
Image img = (Image)sender;
DataObject dataObject = new DataObject(typeof(ImageSource), img.Source);
DragDrop.DoDragDrop(img, dataObject, DragDropEffects.All);
}
private void grid_MouseMove(object sender, MouseEventArgs e)
{
double y = e.GetPosition(grid).Y;
double start = 0.0;
row = 0;
foreach (RowDefinition rd in grid.RowDefinitions)
{
start += rd.ActualHeight;
if (y < start)
{
break;
}
row++;
}
double x = e.GetPosition(grid).X;
start = 0.0;
col = 0;
foreach (ColumnDefinition cd in grid.ColumnDefinitions)
{
start += cd.ActualWidth;
if (x < start)
{
break;
}
col++;
}
}
private void grid_Drop(object sender, DragEventArgs e)
{
Image imageControl = new Image { Stretch = Stretch.Fill };
if ((e.Data.GetData(typeof(ImageSource)) != null))
{
ImageSource image = e.Data.GetData(typeof(ImageSource)) as ImageSource;
imageControl = new Image() { Stretch = Stretch.Fill, Source = image };
}
else
{
if ((e.Data.GetData(typeof(Image)) != null))
{
Image image = e.Data.GetData(typeof(Image)) as Image;
imageControl = image;
if (((Grid)sender).Children.Contains(image))
{
((Grid)sender).Children.Remove(image);
}
}
}
Grid.SetColumn(imageControl, col);
Grid.SetRow(imageControl, row);
((Grid)sender).Children.Add(imageControl);
}
you can get the position in the grid_Drop method using Mouse.GetPosition()like this:
private void grid_Drop(object sender, DragEventArgs e)
{
Point location = Mouse.GetPosition(grid);
//do calculation from mouse_move method to get the col and row
Image imageControl = new Image { Stretch = Stretch.Fill};
if ((e.Data.GetData(typeof(ImageSource)) != null))
{
ImageSource image = e.Data.GetData(typeof(ImageSource)) as ImageSource;
imageControl = new Image() { Stretch = Stretch.Fill, Source = image };
}
else
{
if ((e.Data.GetData(typeof(Image)) != null))
{
Image image = e.Data.GetData(typeof(Image)) as Image;
imageControl = image;
if (((Grid)sender).Children.Contains(image))
{
((Grid)sender).Children.Remove(image);
}
}
}
Grid.SetColumn(imageControl, col);
Grid.SetRow(imageControl, row);
((Grid)sender).Children.Add(imageControl);
}

Canvas adds lines without drawing it

I'm currently trying out WPF for the first time, because I have used WinForms before. I started with a little practice and wanted to create a program which draws a line to wherever you click on a canvas. I programatically added the line to the canvas, but it seems that it doesn't draw it. The lines become children of the canvas though.
C# Code
private ArrayList arl = new ArrayList();
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
drawArea.Children.Clear();
arl.Add(Mouse.GetPosition(drawArea));
Point[] points = new Point[arl.Count];
for (int i = 0; i < arl.Count; i++)
points[i] = (Point)arl[i];
Line[] lines = new Line[points.Length - 1];
if(lines.Count() > 0)
{
for (int i = 0; i < lines.Length; i++)
{
lines[i] = new Line();
lines[i].Stroke = SystemColors.WindowFrameBrush;
lines[i].X1 = points[i + 1].X;
lines[i].X2 = points[i].X;
lines[i].Y1 = points[i + 1].Y;
lines[i].Y2 = points[i].Y;
}
foreach (var item in lines)
drawArea.Children.Add(item);
}
}
XAML
<Window x:Class="WPFttest.MainWindow"
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:WPFttest"
mc:Ignorable="d"
Title="MainWindow" Height="362" Width="525" MouseDown="Window_MouseDown" BorderBrush="Red" ResizeMode="NoResize" KeyDown="Window_KeyDown" WindowStyle="None">
<Grid x:Name="mainGrid" HorizontalAlignment="Left" Height="362" VerticalAlignment="Top" Width="525" OpacityMask="#00000000">
<Canvas x:Name="drawArea" HorizontalAlignment="Left" Height="312" Margin="0,50,0,0" VerticalAlignment="Top" Width="525" Background="White" MouseDown="Canvas_MouseDown">
</Canvas>
<Grid HorizontalAlignment="Left" Height="50" VerticalAlignment="Top" Width="525" MouseDown="Grid_MouseDown_1" OpacityMask="#00000000" Background="#00000000"/>
</Grid>

WPF Changing fill colour of ellipse

So I'm trying to make 8 circles which all have different fill colours and all have different blinking speeds. So far I have been able to make them blink at different speeds, but I'm having trouble with making them all have different colours. My code so far:
private void Appear(Ellipse element, double duration, Brush colour)
{
element.Fill = colour;
DoubleAnimation db = new DoubleAnimation();
db.From = 0.0;
db.To = 1.0;
db.Duration = new Duration(TimeSpan.FromSeconds(duration));
db.RepeatBehavior = RepeatBehavior.Forever;
element.BeginAnimation(Ellipse.OpacityProperty, db);
}
private Brush SetEllipseColour(Ellipse element)
{
Random rnd = new Random();
int red = rnd.Next(0, 255);
int green = rnd.Next(0, 255);
int blue = rnd.Next(0, 255);
Brush fillColour = new SolidColorBrush(Color.FromRgb((byte)red, (byte)green, (byte)blue));
return fillColour;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
List<Ellipse> elements = new List<Ellipse>();
elements.Add(Circle1);
elements.Add(Circle2);
elements.Add(Circle3);
elements.Add(Circle4);
elements.Add(Circle5);
elements.Add(Circle6);
elements.Add(Circle7);
elements.Add(Circle8);
Random rnd = new Random();
foreach (Ellipse element in elements)
{
int r = rnd.Next(1, 10);
double duration = (Double)r / 10;
Appear(element, duration, SetEllipseColour(element));
}
}
And my WPF:
<Canvas Margin="10">
<Ellipse
x:Name="Circle1"
Fill="Black"
Height="100"
Width="100"/>
<Ellipse
x:Name="Circle2"
Fill="Black"
Height="100"
Width="100"
Margin="120,0,0,0"/>
<Ellipse
x:Name="Circle3"
Fill="Black"
Height="100"
Width="100"
Margin="240,0,0,0"/>
<Ellipse
x:Name="Circle4"
Fill="Black"
Height="100"
Width="100"
Margin="360,0,0,0"/>
<Ellipse
x:Name="Circle5"
Fill="Black"
Height="100"
Width="100"
Margin="0,120,0,0"/>
<Ellipse
x:Name="Circle6"
Fill="Black"
Height="100"
Width="100"
Margin="120,120,0,0"/>
<Ellipse
x:Name="Circle7"
Fill="Black"
Height="100"
Width="100"
Margin="240,120,0,0"/>
<Ellipse
x:Name="Circle8"
Fill="Black"
Height="100"
Width="100"
Margin="360,120,0,0"/>
</Canvas>
<Button x:Name="button1" Content="Start" Width="80" Height="20" Margin="0,200,0,0" Click="button1_Click"/>
Note: I know I can compress / change my code to make it neater or better, but for now I just want to get the colours working.
So currently the code I have changes the fill colour of all Ellipse elements, but I want to change it to just affect each Circle. How would I go about doing this?
Edit:
For those who are confused what Im trying to ask, I do not know how to individually change the fill colour of every Circle.
Set the instance of the Random class at the class level, check the below example, by clicking on the the Button that says Blink Em! the animation is triggered.
The XAML
<Window x:Class="Blink.MainWindow"
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:Blink"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" WindowState="Maximized">
<Grid VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button x:Name="BlinkEm" Content="Blink Em!" Height="30" Click="BlinkEm_Click"/>
<StackPanel x:Name="Container" Orientation="Horizontal" Loaded="Container_Loaded" Grid.Row="1"/>
</Grid>
</Window>
The code-behind
namespace Blink
{
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public Random random = new Random();
public MainWindow()
{
InitializeComponent();
}
public List<Ellipse> CreateCircles(int count)
{
List<Ellipse> circles = new List<Ellipse>();
for (int i = 0; i < count; i++)
{
var circle = new Ellipse
{
Height = 100,
Width = 100,
Margin = new Thickness(10),
Fill = Brushes.SkyBlue
};
circles.Add(circle);
}
return circles;
}
public void AddCircles()
{
var circles = this.CreateCircles(8);
foreach (var circle in circles)
{
Container.Children.Add(circle);
}
}
private void Container_Loaded(object sender, RoutedEventArgs e)
{
AddCircles();
}
private void BlinkEm_Click(object sender, RoutedEventArgs e)
{
foreach (Ellipse circle in Container.Children)
{
circle.Fill = GetRandomColor();
circle.BeginAnimation(Ellipse.OpacityProperty, GetBlinkAnimation());
}
}
public Brush GetRandomColor()
{
var red = Convert.ToByte(random.Next(0, 255));
var green = Convert.ToByte(random.Next(0, 255));
var blue = Convert.ToByte(random.Next(0, 255));
return new SolidColorBrush(Color.FromRgb(red, green, blue));
}
public DoubleAnimation GetBlinkAnimation()
{
var duration = random.NextDouble();
var animation = new DoubleAnimation
{
From = 0.0,
To = 1.0,
Duration = new Duration(TimeSpan.FromSeconds(duration)),
RepeatBehavior = RepeatBehavior.Forever
};
return animation;
}
}
}
I think your mistake here is that the Random object is being recreated every time. Try putting that into a field and initializing it once, or by sending it as a parameter to your SetEllipseColor method.
Due to random number generators not actually being random, they derive their "initial" random values from a seed value, often the current time. This means if you create a bunch of new Random instances in a very short time, they are likely to end up with the same seed and thus the same value.
(In more general terms, "Appear" and "SetEllipseColor" aren't very good method names. The former is vague and the latter doesn't actually describe what that method is doing.)

Image control and Image resizing when Stretch is set to Uniform

I have this peculiar problem. I am having a user control . I am making an app for Windows 8.1 where I would choose an image from my Picture gallery. The image would open in my app with Stretch is Uniform and Horizontal And vertical alignment to center.
My user control will appear where I tap on the image. Now the problem is , when the image Stretch was none , I was able to magnify the correct region (around my click) , but now when I make it Stretch to Uniform and Set the horizontal and vertical Alignment to Center , I am getting other pixel information in my user control.
I want to know how to fix it.Any how , the images can be of 2*Full HD also or they can be HD or even less.
Secondly , I want to know the boundaries of the image . With boundaries I want to say that , my user control shouldnt go above the boundaries of the image .
How to implement that. If my code is needed , I would paste it , If required.
Have this video for reference . This is what I have to develop ! I have the user control ready and I am getting exact pixels for Stretch=NONE , and no Horizontal And Vertical Alignment set.
This is my code for my app
I believe the issue is with how you use the control, rather than the image. If you avoid doing the bitmap cropping and replacing, it would speed up dramatically and likely work for all stretch types.
I've modified the source to show this - removing the Cropping completely. If you need cropping for other reasons, you should consider using the unsafe keyword (and property setting to allow) in order to dramatically speed up its use.
Also, to avoid the lagging/jumping upward, I added IsHitTestVisible="False" so that your delta wouldn't be interrupted by hovering over your image.
I see you have the 45-degree code already - since it wasn't in your source, I only added an example of 90 degree rotation when you get to the sides - so you can see how to set a RenderTransformOrigin point.
MainPage.xaml:
<Page x:Name="page1"
x:Class="controlMagnifier.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:controlMagnifier"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid x:Name="ParentGrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" PointerReleased="ParentGrid_OnPointerReleased" >
<Canvas x:Name="InkPresenter" Height="auto" Width="auto">
<Image Stretch="Uniform" x:Name="image2" >
<Image.Source >
<BitmapImage UriSource="/Assets/wallpaper.jpg" />
</Image.Source>
</Image>
</Canvas>
<local:MagnifierUsercontrol x:Name="MagnifyTip" Visibility="Collapsed" ManipulationMode="All"
IsHitTestVisible="False" Height="227" Width="171"
VerticalContentAlignment="Bottom" HorizontalContentAlignment="Center">
</local:MagnifierUsercontrol>
</Grid>
</Page>
MainPage.xaml.cs:
using System;
using Windows.Foundation;
using Windows.Storage;
using Windows.UI.Input;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
namespace controlMagnifier
{
public sealed partial class MainPage : Page
{
public const int XAxis = 200;
public const int YAxis = 435;
private readonly RotateTransform myRotateTransform = new RotateTransform {CenterX = 0.5, CenterY = 1};
private readonly ScaleTransform myScaleTransform = new ScaleTransform {ScaleX = 1, ScaleY = 1};
private readonly TransformGroup myTransformGroup = new TransformGroup();
private readonly TranslateTransform myTranslateTransform = new TranslateTransform();
public WriteableBitmap CurrentBitmapObj, CurrentCroppedImage = null;
public Point currentContactPt, GridPoint;
public Thickness margin;
public PointerPoint pt;
public double xValue, yValue;
public MainPage()
{
InitializeComponent();
ParentGrid.Holding += Grid_Holding;
image2.PointerMoved += InkCanvas_PointerMoved;
image2.PointerReleased += ParentGrid_OnPointerReleased;
margin = MagnifyTip.Margin;
image2.CacheMode = new BitmapCache();
myTransformGroup.Children.Add(myScaleTransform);
myTransformGroup.Children.Add(myRotateTransform);
myTransformGroup.Children.Add(myTranslateTransform);
MagnifyTip.RenderTransformOrigin = new Point(0.5, 1);
MagnifyTip.RenderTransform = myTransformGroup;
}
private void Grid_Holding(object sender, HoldingRoutedEventArgs e)
{
try
{
GridPoint = e.GetPosition(image2);
myTranslateTransform.X = xValue - XAxis;
myTranslateTransform.Y = yValue - YAxis;
MagnifyTip.RenderTransform = myTransformGroup;
MagnifyTip.Visibility = Visibility.Visible;
}
catch (Exception)
{
throw;
}
}
private void InkCanvas_PointerMoved(object sender, PointerRoutedEventArgs e)
{
try
{
pt = e.GetCurrentPoint(image2);
currentContactPt = pt.Position;
xValue = currentContactPt.X;
yValue = currentContactPt.Y;
if (xValue > 300)
{
myRotateTransform.Angle = -90;
}
else if (xValue < 100)
{
myRotateTransform.Angle = 90;
}
else
{
myRotateTransform.Angle = 0;
}
MagnifyTip.RenderTransform = myRotateTransform;
myTranslateTransform.X = xValue - XAxis;
myTranslateTransform.Y = yValue - YAxis;
MagnifyTip.RenderTransform = myTransformGroup;
}
catch (Exception)
{
throw;
}
finally
{
e.Handled = true;
}
}
private async void StoreCrrentImage()
{
try
{
var storageFile =
await
StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/wallpaper.jpg",
UriKind.RelativeOrAbsolute));
using (
var fileStream =
await storageFile.OpenAsync(FileAccessMode.Read))
{
var bitmapImage = new BitmapImage();
await bitmapImage.SetSourceAsync(fileStream);
var writeableBitmap =
new WriteableBitmap(bitmapImage.PixelWidth, bitmapImage.PixelHeight);
fileStream.Seek(0);
await writeableBitmap.SetSourceAsync(fileStream);
CurrentBitmapObj = writeableBitmap;
writeableBitmap.Invalidate();
}
}
catch (Exception)
{
// Graphics g=new Graphics();
throw;
}
finally
{
}
}
private void ParentGrid_OnPointerReleased(object sender, PointerRoutedEventArgs e)
{
MagnifyTip.Visibility = Visibility.Collapsed;
}
}
}
MagnifierUsercontrol.xaml:
<UserControl
x:Class="controlMagnifier.MagnifierUsercontrol"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:controlMagnifier"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" Height="227" Width="171">
<Canvas x:Name="controlCanvas" x:FieldModifier="public" Height="Auto" Width="Auto" >
<Grid Height="227" Width="171" HorizontalAlignment="Center" Canvas.Left="0" Canvas.Top="0">
<Border x:FieldModifier="public" x:Name="imgBorder" Width="150" CornerRadius="50,50,50,50" Margin="13,25,13,97">
<Border.Background>
<ImageBrush x:FieldModifier="public" x:Name="image1" />
</Border.Background>
</Border>
<TextBlock x:Name="txtreading" Height="30" Width="80" Margin="0,-145,0,0" FontWeight="Bold" Foreground="Red" FontSize="20" Text="ABC" TextAlignment="Center" />
<!--<Image Height="120" Width="150" Margin="0,-50,0,0" Source="Assets/SmallLogo.scale-100.png" ></Image>-->
<Path x:Name="MagnifyTip" Data="M25.533,0C15.457,0,7.262,8.199,7.262,18.271c0,9.461,13.676,19.698,17.63,32.338 c0.085,0.273,0.34,0.459,0.626,0.457c0.287-0.004,0.538-0.192,0.619-0.467c3.836-12.951,17.666-22.856,17.667-32.33 C43.803,8.199,35.607,0,25.533,0z M25.533,32.131c-7.9,0-14.328-6.429-14.328-14.328c0-7.9,6.428-14.328,14.328-14.328 c7.898,0,14.327,6.428,14.327,14.328C39.86,25.702,33.431,32.131,25.533,32.131z" Fill="#FFF4F4F5" Stretch="Fill" Stroke="Black" UseLayoutRounding="False" Height="227" Width="171" />
</Grid>
</Canvas>
</UserControl>
Let me know if this helps or if there is further toward your specific question.

Custom UserControl not showing up in ListBox

I have a problem displaying custom UserControls in my ListBox programmatically. I just can't seem to figure out what is wrong. The list-item shows up without image or text.
My project consists of:
MainWindow.xaml
MainWindow.xaml.cs
cvMenuItem.xaml
cvMenuItem.xaml.cs
Code of MainWindow.xaml.cs
private void cvMenuItem_MouseLeftButtonUp_1(object sender, MouseButtonEventArgs e)
{
lstContacts.Items.Clear();
cvMenuItem test = new cvMenuItem("test",
Environment.GetEnvironmentVariable("USERPROFILE") + #"\Downloads\images.jpg");
lstContacts.Items.Add(test);
}
Code of cvMenuItem.xaml.cs
public partial class cvMenuItem : UserControl
{
public cvMenuItem()
{
InitializeComponent();
}
public cvMenuItem(string text, string Logo)
{
this.Height = 50;
this.Width = 186;
txtService = new TextBlock() { Width = 100, Height = 50 };
imgLogo = new Image() { Width = 50, Height = 50 };
//Just found out, adding the objects as childeren partially works
this.AddChild(imgLogo);
//But I can't add txtService as Childeren
//this.AddChild(txtService);
this.Services = text;
this.Logo = Logo;
}
public string Services
{
get{ return txtService.Text.ToString() }
set
{
txtService.Text = value;
}
}
public string Logo
{
get{ return imgLogo.Source.ToString(); }
set
{
var uriSource = new Uri(value);
imgLogo.Source = new BitmapImage(uriSource);
}
}
My cvMenuItem.xaml.cs
<UserControl x:Class="WpfApplication1.cvMenuItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" Height="50" Width="186">
<Grid Width="186" VerticalAlignment="Top">
<Image Name="imgLogo" Height="50" Width="50" HorizontalAlignment="Left" VerticalAlignment="Top" OpacityMask="{DynamicResource {x:Static SystemColors.ActiveCaptionTextBrushKey}}" />
<TextBlock Name="txtService" HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Bottom" Height="18" Width="121" Margin="70,0,0,18" RenderTransformOrigin="0.499,1.932"/>
</Grid>
</UserControl>
First of all you need to call InitializeComponent in the custom constructor you have added, as that is needed to process the XAML properly. Otherwise all the controls you add in the XAML will be null when running the application.
Additionally it makes no sense to create the TextBlock and Image again in the code-behind. You just have to use the ones created in the XAML.
So to get it working, change the code in the constructor to the following:
public cvMenuItem(string text, string Logo)
{
InitializeComponent();
this.Height = 50;
this.Width = 186;
this.Services = text;
this.Logo = Logo;
}

Categories

Resources