I have a ListView-derived class which creates a bunch of user controls that are Panel-derived classes that contain a few controls each, most importantly a Image control (m_labelIcon). I am setting the image source for this control dynamically to one of the PNGs in my resource:
Uri uri = new Uri("/MyApp;component/Common/Main/res/drawable/some_icon.png");
StreamResourceInfo resourceInfo = Application.GetResourceStream(uri);
BitmapImage bitmapSource = new BitmapImage();
bitmapSource.CreateOptions = BitmapCreateOptions.None;
bitmapSource.SetSource(resourceInfo.Stream);
m_labelIcon.Source = bitmapSource;
However, when the list view appears, the images are all missing. If I scroll the list to the very bottom and then back to the top, the images start appearing. I've specified BitmapCreateOptions.None, which should prevent delay-loading the images (they are in my resource and not on the web).
I've also tried using the ImageOpened event, but this doesn't work.
Any thoughts?
Thanks,
swine
After hours of the debugging, I stumbled upon the simple solution. Even though I was overriding ArrangeOverride() and MeasureOverride() like so:
protected override Size MeasureOverride(Size availableSize)
{
Size panelDesiredSize = new Size();
double height = Math.Max(getIconSizeToUseInPixels(),
m_labelName.DesiredSize.Height);
panelDesiredSize = new Size(availableSize.Width, height);
return panelDesiredSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
double x = 0;
double y = 0;
m_labelName.Measure(finalSize);
double iconWidth = getIconSizeToUseInPixels();
Size iconSize = new Size(iconWidth, iconWidth);
double nameWidth = m_labelName.DesiredSize.Width;
double nameHeight = m_labelName.DesiredSize.Height;
m_labelIcon.Arrange(new Rect(
new Point(x, y), iconSize));
m_labelName.Arrange(new Rect(
new Point(iconWidth, y + (finalSize.Height - nameHeight) / 2),
new Size(nameWidth, nameHeight)));
m_labelName.Width = nameWidth;
m_labelName.Height = nameHeight;
return finalSize; // Returns the final Arranged size
}
I still needed to set the Width and the Height properties of the Image control manually in the constructor of my custom control like so:
THIS FIXED THE PROBLEM:
m_labelIcon.Width = getIconSizeToUseInPixels();
m_labelIcon.Height = getIconSizeToUseInPixels();
Related
I am trying to add different page contents in order to pass it to the Print Manager interface. However, when trying to add multiple BitmapImages, it's returning a "Element is already the child of another element." error.
Here's what my current code looks like:
Canvas page = new Canvas
{
Width = pageDescription.PageSize.Width,
Height = pageDescription.PageSize.Height
};
Canvas viewablePage = new Canvas()
{
Width = pageDescription.ViewablePageSize.Width,
Height = pageDescription.ViewablePageSize.Height
};
viewablePage.SetValue(Canvas.LeftProperty, pageDescription.Margin.Width);
viewablePage.SetValue(Canvas.TopProperty, pageDescription.Margin.Height);
// The image "frame" which also acts as a viewport
Grid photoView = new Grid
{
Width = pageDescription.PictureViewSize.Width,
Height = pageDescription.PictureViewSize.Height
};
The foreach loop wherein a different image is added to the a different page
foreach(var btm in bitmapImages)
{
Image image = new Image
{
Source = btm,
HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center,
VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center
};
// Use the real image size when croping or if the image is smaller then the target area (prevent a scale-up).
if ((btm.PixelWidth <= pageDescription.PictureViewSize.Width &&
btm.PixelHeight <= pageDescription.PictureViewSize.Height))
{
image.Stretch = Stretch.None;
image.Width = bitmap.PixelWidth;
image.Height = bitmap.PixelHeight;
}
photoView.Children.Add(image);
viewablePage.Children.Add(photoView);
page.Children.Add(viewablePage);
pages.Add(page);
}
bitmapImages is a list of bitmaps. It works if there's only one image to be added but when adding < 1 image to a page, it returns the error. Do you have any suggestions on how should I implement this?
Thanks alot.
Each UI element in UWP can only be used in the UI in one place at one time.
You need to define the UI element every loop.
foreach(var btm in bitmapImages)
{
Canvas page = new Canvas
{
Width = pageDescription.PageSize.Width,
Height = pageDescription.PageSize.Height
};
Canvas viewablePage = new Canvas()
{
Width = pageDescription.ViewablePageSize.Width,
Height = pageDescription.ViewablePageSize.Height
};
viewablePage.SetValue(Canvas.LeftProperty, pageDescription.Margin.Width);
viewablePage.SetValue(Canvas.TopProperty, pageDescription.Margin.Height);
// The image "frame" which also acts as a viewport
Grid photoView = new Grid
{
Width = pageDescription.PictureViewSize.Width,
Height = pageDescription.PictureViewSize.Height
};
Image image = new Image
{
Source = btm,
HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center,
VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center
};
// Use the real image size when croping or if the image is smaller then the target area (prevent a scale-up).
if ((btm.PixelWidth <= pageDescription.PictureViewSize.Width &&
btm.PixelHeight <= pageDescription.PictureViewSize.Height))
{
image.Stretch = Stretch.None;
image.Width = bitmap.PixelWidth;
image.Height = bitmap.PixelHeight;
}
photoView.Children.Add(image);
viewablePage.Children.Add(photoView);
page.Children.Add(viewablePage);
pages.Add(page);
}
I have lines of C# code with which I am able to record screen.
But I cannot find a workaround in order to determine custom video output size.
My screen resolution is 1920x1080, although i try to assign new size for the record It remains unchanged.
(Library: Microsoft Expression Encoder, all dependencies are included)
The code I used in Button click event:
ScreenCaptureJob _screenCaptureJob = new ScreenCaptureJob();
Rectangle _screenRectangle = Screen.PrimaryScreen.Bounds;
_screenCaptureJob.CaptureRectangle = _screenRectangle;
_screenCaptureJob.ScreenCaptureVideoProfile.Size = new Size(600, 400); //By doing this Is it supposed to resize original size to 600x400 pixels?
_screenCaptureJob.ScreenCaptureVideoProfile.AutoFit = true;
_screenCaptureJob.ShowFlashingBoundary = false;
_screenCaptureJob.ScreenCaptureVideoProfile.FrameRate = 20;
_screenCaptureJob.CaptureMouseCursor = true;
_screenCaptureJob.ScreenCaptureVideoProfile.SmoothStreaming = true;
_screenCaptureJob.ScreenCaptureVideoProfile.Quality = 20;
_screenCaptureJob.OutputScreenCaptureFileName = string.Format(#"C:\test.wmv");
if (File.Exists(_screenCaptureJob.OutputScreenCaptureFileName))
{
File.Delete(_screenCaptureJob.OutputScreenCaptureFileName);
}
_screenCaptureJob.Start();
Thanks in advance!
What you need to do is to set the _screenRectangle to your custom dimensions:
_screenCaptureJob.CaptureRectangle = new Rectangle(0, 0, 600, 400);
The screen recording size can be left unassigned.
Greetings,
Nikolay
I'm trying to print out some information from my wpf-application. I found some code to make what I want to print to fit one page and it does the job very well. The problem is that after I print what i want, the method downscale my wpf-control, which is a groupbox with a chart in it. How do i scale the size of the groupbox back to what it was before the scaling?
private void PrintUT_Click(object sender, RoutedEventArgs e)
{
PrintDialog printDlg = new System.Windows.Controls.PrintDialog();
if (printDlg.ShowDialog() == true)
{
//get selected printer capabilities
System.Printing.PrintCapabilities capabilities = printDlg.PrintQueue.GetPrintCapabilities(printDlg.PrintTicket);
//get scale of the print wrt to screen of WPF visual
double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth / this.GBProsjektTimer.ActualWidth, capabilities.PageImageableArea.ExtentHeight /
this.GBProsjektTimer.ActualHeight);
//Transform the Visual to scale
this.GBProsjektTimer.LayoutTransform = new ScaleTransform(scale, scale);
//get the size of the printer page
Size sz = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
//update the layout of the visual to the printer page size.
this.Measure(sz);
this.Arrange(new Rect(new Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight), sz));
//now print the visual to printer to fit on the one page.
printDlg.PrintVisual(this.GBProsjektTimer, "First Fit to Page WPF Print");
}
}
Found the answer! Just replace objecToPrint with your object. In my case that would be this.GBProsjektTimer.Width = double.Nan
objectToPrint.Width = double.NaN;
objectToPrint.UpdateLayout();
objectToPrint.LayoutTransform = new ScaleTransform(1, 1);
Size size = new Size(capabilities.PageImageableArea.ExtentWidth,
capabilities.PageImageableArea.ExtentHeight);
objectToPrint.Measure(size);
objectToPrint.Arrange(new Rect(new Point(capabilities.PageImageableArea.OriginWidth,
capabilities.PageImageableArea.OriginHeight), size));
I have an Image control, generated in runtime. It renders correct size when displaying. But I can't get size of that element. Width and Height is NaN. ActualWidth and ActualHeight is always 0.0 and control never fires SizeChanged event.
I'm also generating TextBoxes in the runtime and I can't get size of them too.
The code that generates image is bellow.
ExtendedImage image = new ExtendedImage();
image.Name = "element" + item.Id;
if (item.Text.ToUpperInvariant().EndsWith(".GIF"))
{
var gif = BookReader.Imaging.GIFDecoder.Decode(Application.GetResourceStream(new Uri("Files/Books/" + item.BookId + "/" + item.Text, UriKind.Relative)).Stream);
image.Source = gif.Frames[0].Image;
}
else
{
var img = new BitmapImage(new Uri("/Files/Books/" + item.BookId + "/" + item.Text, UriKind.Relative));
image.Source = img;
}
image.SetValue(Canvas.LeftProperty, (double)item.LocationX);
image.SetValue(Canvas.TopProperty, (double)(Application.Current.Host.Content.ActualHeight - item.LocationY));
image.SizeChanged += (o, e) =>
{
var sender = o as ExtendedImage;
image.SetValue(UIElement.RenderTransformOriginProperty, new Point(0.5, 0.5));
};
image.InvalidateMeasure();
if (!item.Visible)
{
image.Visibility = System.Windows.Visibility.Collapsed;
}
ContentPanel.Children.Add(image);
You can't access the size of the image before it's been rendered. And you can't render a item in a Canvas, without it having a explicit size.
So your problem is that you're attempting to get the size of the image before it's actually been rendered.
If the container of the Image has Height and Width, the image should have it as well. Try to put your Image into a Grid or StackPanel and set the size explicitly.
I created an Image with this code
OpenFileDialog dlg = new OpenFileDialog();
dlg.FileName = ""; // Default file name
myImage = new Image();
try
{
Nullable<bool> result = dlg.ShowDialog();
if (result == true)
{
string sUri = #dlg.FileName;
Uri src = new Uri(sUri, UriKind.RelativeOrAbsolute);
BitmapImage bmp = new BitmapImage(src);
myImage.Source = bmp;
myImage.Width = 100;
myImage.Height = 100;
}
}
I can zoom in/out on this image
public void Scale(int i, Point center)
{
Matrix m = myImage.RenderTransform.Value;
if (i > 0)
m.ScaleAtPrepend(1.1, 1.1, center.X, center.Y);
else
m.ScaleAtPrepend(1 / 1.1, 1 / 1.1, center.X, center.Y);
myImage.RenderTransform = new MatrixTransform(m);
}
but when I get the ActualWidth or Width or ActualHeight/Height returns the number 100. this means that these changes not applied to origin image (myImage).
Now How to apply the changes (zoom or any changes) to origin Image?
Tanx all;
Transforms only affect the appearance / layout of the object they are applied to and won't make any changes directly to the source. For this you'll need to resize the image yourself, reading the values of the scaling and applying those to the original width and height.
Take a look at something like AForge.Net which has myriad methods for manipulating images allowing control over the quality of the transformation etc.