Resolution dependent backgrounds in Windows Phone 8 - c#

I am following this MSDN article to create resolution dependent backgrounds in Windows Phone 8, but it's showing blank background always.
Any one has idea what's wrong with it? Anybody has any alternative solutions?

public enum Resolutions { WVGA, WXGA, HD720p, HD };
private static bool IsWvga
{
get
{
return App.Current.Host.Content.ScaleFactor == 100;
}
}
private static bool IsWxga
{
get
{
return App.Current.Host.Content.ScaleFactor == 160;
}
}
private static bool Is720p
{
get
{
return App.Current.Host.Content.ScaleFactor == 150;
}
}
private static bool IsHD
{
get
{
return App.Current.Host.Content.ScaleFactor == 150;
}
}
Add this to the top of your class and use these static variables to set resolution specific images. You said you want to set "resolution dependent backgrounds", from which I understand you want to set some image on the background? If you want the image to the background of the page then set ImageBrush of your LayoutRoot Grid to resolution specific images ( 480x800.jpg, 720x1280.jpg etc) like this
ImageBrush image = new ImageBrush();
if (IsWvga)
{
//set your bitmap
}
else if (IsWxga)
{
//set your bitmap
}
else if (Is720p)
{
//set your bitmap
}
else if(IsHD)
{
//set your bitmap
}
image.Stretch = Stretch.UniformToFill;
LayoutRoot.Background = image;
OR
if you want your screen UI elements to fit in the resolutions then set the height of your UI elements to auto in XAML, or set the resolution specific height of your UI elements on the OnNavigatedTo event of your page. This may be any random grid of your page which needs to fit in
if (IsWvga)
{
grid.Height = 500;
}
else if (IsWxga)
{
grid.Height = 600;
}
else if (Is720p)
{
grid.Height = 700;
}
else if (IsHD)
{
grid.Height = 800;
}

MSDN article has mistake in MultiResImageChooser class, MultiResImageChooser is written as MultiResImageChooserUri & relative URIs are missing leading slash. Correct class is given below.
public class MultiResImageChooser
{
public Uri BestResolutionImage
{
get
{
switch (ResolutionHelper.CurrentResolution)
{
case Resolutions.HD:
return new Uri("/Assets/MyImage.screen-720p.jpg", UriKind.Relative);
case Resolutions.WXGA:
return new Uri("/Assets/MyImage.screen-wxga.jpg", UriKind.Relative);
case Resolutions.WVGA:
return new Uri("/Assets/MyImage.screen-wvga.jpg", UriKind.Relative);
default:
throw new InvalidOperationException("Unknown resolution type");
}
}
}
}

Related

How to display tool tip over a transparent image placed on a Winform button

I am displaying a transparent icon (32x32) of a red triangle in the upper right of a button control that signifies an error exists. Additionally, when the user hovers over the icon, a tool tip is displayed.
I have been able to display the icon and the associated tool tip. The problem is a transparent 32x32 icon with the red triangle being only 12x12. The tool tip should only trigger when hovering over the red triangle and not the transparent space.
Attempts have been made to display the triangle as a button as well as a picture box, however the tool tip still triggers in the transparent space. Additionally, the error provider was first used as a goal of what I am trying to accomplish.
UI items:
Button control: "btnAttachments"
Error Provider control: "errManager"
public class StackTest
{
private static Dictionary<string, Control> _errorMessages = new Dictionary<string, Control>();
public StackTest()
{
InitializeComponent();
InitErrors();
}
private void InitErrors()
{
_errorMessages.Clear();
AddErrorControl(btnAttachments, "Missing file attachment(s).");
//errManager.SetError(btnAttachments, "Missing file attachment(s)."); errManager.SetIconPadding(btnAttachments, -32);
}
private void AddErrorControl(Control control, string message = null, Enum selectedImage = null, EventHandler handler = null)
{
string name = "errFor" + control.Name;
if (_errorMessages.ContainsKey(name)) { return; }
Button errorIcon = CreateErrorControl(name, control);
errorIcon.BackgroundImage = Theme.GetImage(selectedImage ?? eImages_OtherIcons.Error_TopRight_Small);
//PictureBox errorIcon = CreateErrorControl2(name);
//errorIcon.Image = Theme.GetImage(selectedImage ?? eImages_OtherIcons.Error_TopRight_Small);
//errorIcon.Image = Bitmap.FromHicon((Theme.GetIcon(selectedImage ?? eImages_OtherIcons.Error_TopRight_Small)).Handle);
if (null != handler) { errorIcon.Click += handler; }
new ToolTip().SetToolTip(errorIcon, message);
errorIcon.Tag = message;
control.Controls.Add(errorIcon);
control.Controls[name].Location = new Point(control.Width - errorIcon.Width +20 , 0 );
_errorMessages.Add(name, errorIcon);
}
private Button CreateErrorControl(string name, Control control)
{
var errorIcon = new Button();
errorIcon.Name = name;
errorIcon.Size = new Size(32, 32);
//errorIcon.Location = new Point(control.Width - errorIcon.Width, 0);
errorIcon.Cursor = Cursors.Hand;
errorIcon.FlatStyle = FlatStyle.Flat;
errorIcon.BackColor = Color.Fuchsia;
errorIcon.FlatAppearance.MouseDownBackColor = Color.Transparent;
errorIcon.FlatAppearance.MouseOverBackColor = Color.Transparent;
errorIcon.FlatAppearance.BorderSize = 0;
errorIcon.Visible = false;
return errorIcon;
}
private PictureBox CreateErrorControl2(string name)
{
var errorIcon = new PictureBox();
errorIcon.Name = name;
errorIcon.Size = new Size(32, 32);
errorIcon.Cursor = Cursors.Hand;
errorIcon.BackColor = Color.Transparent;
errorIcon.Visible = false;
return errorIcon;
}
}
The built in Error Provider control achieves the desire results that I would like to replicate. Doing so will allow for a more robust application with more custom functionality then what the error provider offers.
Based on the GetPixel suggestion from #TaW, I did further R&D and now have something functional. The Tag of the picture box contains the tool tip message to be displayed. With the picture box being the "sender" of the mouse move, it was easy to extract the image back to a bitmap.
Thanks to all for the feedback.
First, I switched the testing to use CreateErrorControl2 with the PictureBox and added in a MouseMove.
private PictureBox CreateErrorControl2(string name) //, Control control)
{
var errorIcon = new PictureBox();
errorIcon.Name = name;
errorIcon.Size = new Size(32, 32);
errorIcon.Cursor = Cursors.Default;
errorIcon.BackColor = Color.Transparent;
errorIcon.Visible = false;
errorIcon.MouseMove += new MouseEventHandler(DisplayToolTip);
return errorIcon;
}
The following code was also added in support of the DisplayToolTip method.
private bool _toolTipShown = false;
private bool IsTransparent(PictureBox pb, MouseEventArgs e)
{
Color pixel = ((Bitmap)pb.Image).GetPixel(e.X, e.Y);
return (0 == pixel.A && 0 == pixel.R && 0 == pixel.G && 0 == pixel.B);
}
private void DisplayToolTip(object sender, MouseEventArgs e)
{
Control control = (Control)sender;
IsTransparent((PictureBox)control, e);
if (IsTransparent((PictureBox)control, e))
{
_toolTip.Hide(control);
_toolTipShown = false;
}
else
{
if (!_toolTipShown)
{
_toolTip.Show(control.Tag.ToString(), control);
_toolTipShown = true;
}
}
}

First tab icon not resizing iOS TabbedRenderer

I am working on iOS Tabs using custom TabbedRenderer, In renderer page I am resizing & setting icons. But for the first Tab icon not getting resized rest of all tabs setting icons fine.
public class CustomTabRenderer_iOS : TabbedRenderer
{
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
foreach (var item in TabBar.Items)
{
item.Image = GetTabIcon(item.Title);
}
}
private UIImage GetTabIcon(string title)
{
UITabBarItem item = null;
switch (title)
{
case "Dairy":
item = new UITabBarItem("Dairy", UIImage.FromFile("dairy"), 0);
break;
case "My kid":
item = new UITabBarItem("My kid",UIImage.FromFile("kid"),0);
break;
case "Events":
item = new UITabBarItem("Events", UIImage.FromFile("events"), 0);
break;
case "About":
item = new UITabBarItem("About", UIImage.FromFile("about"), 0);
break;
}
var img = (item != null) ? UIImage.FromImage(item.SelectedImage.CGImage, item.SelectedImage.CurrentScale, item.SelectedImage.Orientation) : new UIImage();
var imgR = ResizeImage(img, 20, 20);
return imgR;
}
public UIImage ResizeImage(UIImage sourceImage, float width, float height)
{
UIGraphics.BeginImageContext(new SizeF(width, height));
sourceImage.Draw(new RectangleF(0, 0, width, height));
var resultImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return resultImage;
}
}
Below is TabbedPage from PCL project
<Shared:MyTabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:edTheSIS"
x:Class="edTheSIS.ParentDashboard"
xmlns:Shared="clr-namespace:edTheSIS.Shared;assembly=edTheSIS">
<local:DairyTabPage Icon="dairy" HeightRequest="10" WidthRequest="10" ></local:DairyTabPage>
<local:MykidTab Icon="kid" ></local:MykidTab>
<local:Events Icon="events"></local:Events>
<local:About Icon="about"></local:About>
</Shared:MyTabbedPage>
See below screenshot
second screenshot below
According to the iOS Human Interface Guidelines, the images should be sizes as shown in the table underneath for a tab bar.
If you size the icons accordingly, they should always show right. There would be no reason to resize in code.
When you still want to use the code to resize an icon, update your ViewWillLayoutSubviews method like this, also setting the SelectedImage property:
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
foreach (var item in TabBar.Items)
{
item.Image = GetTabIcon(item.Title);
item.SelectedImage = GetTabIcon(item.Title);
}
}
The tab bar icon size on iOS can be set with the UITabBarItem.ImageInset in a custom TabbedRenderer
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedPageRenderer))]
namespace AppNameSpace.iOS.Renderers
{
class CustomTabbedPageRenderer : TabbedRenderer
{
public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
if (Element is TabbedPage)
if (TabBar?.Items != null)
foreach (var item in TabBar.Items)
item.ImageInsets = new UIEdgeInsets(16, 16, 16, 16);
}
}
}

How to get the real CaptureElement size?

I'm using CaptureElement to display the output of the camera.
Depending on how the user resizes the window, there can be black borders on either left/right or top/bottom of the camera output.
I'd like to get the size of the camera output WITHOUT including the black borders. I've tried many height/width/size fields that CaptureElement has, including ActualWidth, RenderSize.Width etc. but none of them returns the real width/height of the camera.
If the black border is of width 100px, the actual camera output of width 300px, the width fields will return 2*100px+300px = 500px. They all include the black border.
How do I get only the width and height of the actual camera display?
How do I get only the width and height of the actual camera display?
You could use the IMediaEncodingProperties interface to get the width and height of the camera preview stream, and make the CaptureElement control same size with the stream or even you can set the stream size to the CaptureElement. In that cases you may not see the black parts. For example:
<CaptureElement x:Name="myCaptureElement" />
<Button Click="Button_Click">Click me to see a preview</Button>
Code behind
public sealed partial class MainPage : Page
{
private async void Button_Click(object sender, RoutedEventArgs e)
{
try
{
// Using Windows.Media.Capture.MediaCapture APIs
// to stream from webcam
MediaCapture mediaCaptureMgr = new MediaCapture();
await mediaCaptureMgr.InitializeAsync();
MediaStreamType streamType = MediaStreamType.VideoPreview;
// Query all properties of the specified stream type
IEnumerable<StreamPropertiesHelper> allVideoProperties =
mediaCaptureMgr.VideoDeviceController.GetAvailableMediaStreamProperties(streamType).Select(x => new StreamPropertiesHelper(x));
// Query the current preview settings
StreamPropertiesHelper previewProperties = new StreamPropertiesHelper(mediaCaptureMgr.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview));
myCaptureElement.Height = previewProperties.Height;
myCaptureElement.Width = previewProperties.Width;
// Start capture preview.
myCaptureElement.Source = mediaCaptureMgr;
await mediaCaptureMgr.StartPreviewAsync();
}
catch
{
}
}
}
class StreamPropertiesHelper
{
private IMediaEncodingProperties _properties;
public StreamPropertiesHelper(IMediaEncodingProperties properties)
{
if (properties == null)
{
throw new ArgumentNullException(nameof(properties));
}
// This helper class only uses VideoEncodingProperties or VideoEncodingProperties
if (!(properties is ImageEncodingProperties) && !(properties is VideoEncodingProperties))
{
throw new ArgumentException("Argument is of the wrong type. Required: " + typeof(ImageEncodingProperties).Name
+ " or " + typeof(VideoEncodingProperties).Name + ".", nameof(properties));
}
// Store the actual instance of the IMediaEncodingProperties for setting them later
_properties = properties;
}
public uint Width
{
get
{
if (_properties is ImageEncodingProperties)
{
return (_properties as ImageEncodingProperties).Width;
}
else if (_properties is VideoEncodingProperties)
{
return (_properties as VideoEncodingProperties).Width;
}
return 0;
}
}
public uint Height
{
get
{
if (_properties is ImageEncodingProperties)
{
return (_properties as ImageEncodingProperties).Height;
}
else if (_properties is VideoEncodingProperties)
{
return (_properties as VideoEncodingProperties).Height;
}
return 0;
}
}
public uint FrameRate
{
get
{
if (_properties is VideoEncodingProperties)
{
if ((_properties as VideoEncodingProperties).FrameRate.Denominator != 0)
{
return (_properties as VideoEncodingProperties).FrameRate.Numerator /
(_properties as VideoEncodingProperties).FrameRate.Denominator;
}
}
return 0;
}
}
public double AspectRatio
{
get { return Math.Round((Height != 0) ? (Width / (double)Height) : double.NaN, 2); }
}
public IMediaEncodingProperties EncodingProperties
{
get { return _properties; }
}
public string GetFriendlyName(bool showFrameRate = true)
{
if (_properties is ImageEncodingProperties ||
!showFrameRate)
{
return Width + "x" + Height + " [" + AspectRatio + "] " + _properties.Subtype;
}
else if (_properties is VideoEncodingProperties)
{
return Width + "x" + Height + " [" + AspectRatio + "] " + FrameRate + "FPS " + _properties.Subtype;
}
return String.Empty;
}
}
The above code snippet are referenced Set format, resolution, and frame rate for MediaCapture, more details you also can reference CameraResolution official sample.
I've used Sunteen's answer to get the resolution of the camera. Then, I calculated both the camera resolution ratio and the video preview output ratio. Using this information, I could calculate the actual size of the video output.
Here's the solution.
var props = (VideoEncodingProperties) _mediaCapture.VideoDeviceController
.GetMediaStreamProperties(MediaStreamType.VideoPreview);
double cameraWidth = props.Width;
double cameraHeight = props.Height;
double previewOutputWidth = CameraPreview.ActualWidth;
double previewOutputHeight = CameraPreview.ActualHeight;
double cameraRatio = cameraWidth / cameraHeight;
double previewOutputRatio = previewOutputWidth / previewOutputHeight;
double actualWidth = (cameraRatio <= previewOutputRatio) ?
previewOutputHeight * cameraRatio
: previewOutputWidth;
double actualHeight = (cameraRatio <= previewOutputRatio) ?
previewOutputHeight
: previewOutputWidth / cameraRatio;

Is there anyway to wrap the text in the ListView

I have message is too long to fit in the column. I have table with four columns my fourth column is "Message" which has string long string and it doesnot fit in columnwidth. I want to Make the text in column as Warp so that all the text is visible to the user.
ListViewItem lv = new ListViewItem();
lv.Text = det_view.filename;
lv.SubItems.Add(det_view.number.ToString());
lv.SubItems.Add(det_view.Date_Time.ToString());
lv.SubItems.Add(det_view.Message); // here the string too long and need wrap the message
listView1.Items.Add(lv);
Regards
Short of having your listviewitems ownerdrawn, you might have a look at ObjectListView. It will wordwrap just fine and may suite your needs.
If You feel some license problems with ObjectListView, you can use native .Net ListView.
It can also wordwrap in view=Details and setting smallImageList
(with picture height = 32 or more).
You may try Better ListView component, which supports multi-line items with varous text wrapping and trimming methods:
Here is a class inheriting from ListView that will grow your row height to fit the text in a column. I believe the default will not word break. So you would need to implement wordbreak if that's something you want.
class WordWrapListView : ListView
{
private const int LVM_FIRST = 0x1000;
private const int LVM_INSERTITEMA = (WordWrapListView.LVM_FIRST + 7);
private const int LVM_INSERTITEMW = (WordWrapListView.LVM_FIRST + 77);
private Graphics graphics;
public WordWrapListView()
{
this.graphics = this.CreateGraphics();
base.View = View.Details;
this.AutoSizeRowHeight = true;
}
//overriding WndProc because there are no item added events
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
// Detect item insert and adjust the row size if necessary based on the text
// add in LVM_DELETEITEM and LVM_DELETEALLITEMS and reset this.rowHeight if you want to reduce the row height on remove
case WordWrapListView.LVM_INSERTITEMA:
case WordWrapListView.LVM_INSERTITEMW:
{
ListViewItem lvi = this.Items[this.Items.Count - 1];
for (int i = 0; i< lvi.SubItems.Count; ++i)
{
ListViewItem.ListViewSubItem lvsi = lvi.SubItems[i];
string text = lvsi.Text;
int tmpHeight = 0;
int maxWidth = this.Columns[i].Width;
SizeF stringSize = this.graphics.MeasureString(text, this.Font);
if (stringSize.Width > 0)
{
tmpHeight = (int)Math.Ceiling((stringSize.Width / maxWidth) * stringSize.Height);
if (tmpHeight > this.rowHeight)
{
this.RowHeight = tmpHeight;
}
}
}
}
break;
default:
break;
}
base.WndProc(ref m);
}
private void updateRowHeight()
{
//small image list hack
ImageList imgList = new ImageList();
imgList.ImageSize = new Size(this.rowHeight, this.rowHeight);
this.SmallImageList = imgList;
}
[System.ComponentModel.DefaultValue(true)]
public bool AutoSizeRowHeight { get; set; }
private int rowHeight;
public int RowHeight
{
get
{
return this.rowHeight;
}
private set
{
//Remove value > this.rowHeight if you ever want to scale down the height on remove item
if (value > this.rowHeight && this.AutoSizeRowHeight)
{
this.rowHeight = value;
this.updateRowHeight();
}
}
}
// only allow details view
[Browsable(false), Bindable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)]
public new View View
{
get
{
return base.View;
}
set
{
}
}
}
May not be what you need but my solution was to switch to the build-in DataGridView control.

How to make Glass Button ignore form's gradient?

There's some really great code for a glass button here: http://www.lukesw.net/articles/GlassButton.aspx
The only trouble I have with this button is that if I apply a gradient to my forms it affects the color of the button so that it's not quite what I chose at design time. I don't know whether it's the code I'm using to apply the form gradient that's causing this or if the button is not totally opaque or what. I tried fooling around with the button code a bit but didn't get anywhere. You can get the code for the button at the link I posted above. Below is the code I'm using for my form gradient which is located in the form itself right now:
private Color _Color1 = Color.Gainsboro;
private Color _Color2 = Color.Blue;
private float _ColorAngle = 60f;
public Color Color1
{
get { return _Color1; }
set {
_Color1 = value;
this.Invalidate(); // Tell the Form to repaint itself
}
}
public Color Color2
{
get { return _Color2; }
set {
_Color2 = value;
this.Invalidate(); // Tell the Form to repaint itself
}
}
public float ColorAngle
{
get { return _ColorAngle; }
set {
_ColorAngle = value;
this.Invalidate(); // Tell the Form to repaint itself
}
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
Graphics g = pevent.Graphics;
Rectangle rBackground = new Rectangle(0, 0, this.Width, this.Height);
System.Drawing.Drawing2D.LinearGradientBrush bBackground
= new System.Drawing.Drawing2D.LinearGradientBrush(rBackground,
_Color1, _Color2, _ColorAngle);
g.FillRectangle(bBackground, rBackground);
bBackground.Dispose();
}
Any pointers on how I can get this button to display the same at runtime as it does at design time would be greatly appreciated!
In the DrawButtonBackground method in GlowButton.cs, just change the opacity to fully opaque (255):
#region " content "
using (GraphicsPath bb = CreateRoundRectangle(rect, 2))
{
//int opacity = pressed ? 0xcc : 0x7f;
int opacity = 255;
using (Brush br = new SolidBrush(Color.FromArgb(opacity, backColor)))
{
g.FillPath(br, bb);
}
}
#endregion

Categories

Resources