Create a Single Border Around All UIButtons Xamarin - mono

I have roughly 10 buttons in my iOS application using Xamarin and I am looking for a simple way to put a single, black border around all my buttons. Is there a way to do this without hard coding the border into all the buttons?
So far to put a single border around one button I have:
numOne.Layer.BorderWidth = 1;
numOne.Layer.CornerRadius = 4;
numOne.Layer.BorderColor = UIColor.Black.CGColor;
Is there a way to go about doing this for all the buttons that I have?

Or you could create a method that returns the preferred button:
public static class DefaultUIElements
{
public static UIButton GenericButton
{
get
{
UIButton button = new UIButton(UIButtonType.Custom);
button.Layer.BorderWidth = 1;
button.Layer.CornerRadius = 4;
button.Layer.BorderColor = UIColor.Black.CGColor;
return button;
}
}
}

Make your own Button class
(This code is just of the top of my head, and not tested in an IDE)
public class MyButton : UIButton
{
MyButton()
{
Layer.BorderWidth = 1;
Layer.CornerRadius = 4;
Layer.BorderColor = UIColor.Black.CGColor;
}
}

Related

How to override the parent layout/view opacity for certain elements in xamarin forms?

So I'm trying to develop a custom control which has Opacity of about 0.2, and its an entry, but the problem here is if I set the Opacity of the entry, then the Placeholder or the hint text also gets the opacity, and my custom control has an image as well, which gets the opacity as well, is there a way to override this?
I tried setting the alpha in the renderer but that doesn't seem to do the trick,
Here's my renderer and the output I need, but what I'm getting in actual
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || e.NewElement == null)
return;
var element = (ImageEntry)this.Element;
this.Control.Placeholder = element.Placeholder;
var textField = this.Control;
if (!string.IsNullOrEmpty(element.Image))
{
switch (element.ImageAlignment)
{
case ImageAlignment.Left:
textField.LeftViewMode = UITextFieldViewMode.Always;
textField.LeftView = GetImageView(element.Image, element.ImageHeight, element.ImageWidth);
break;
case ImageAlignment.Right:
textField.RightViewMode = UITextFieldViewMode.Always;
textField.RightView = GetImageView(element.Image, element.ImageHeight, element.ImageWidth);
break;
}
}
this.Control.Layer.CornerRadius = 25;
textField.BorderStyle = UITextBorderStyle.None;
textField.Alpha = 1;
CALayer bottomBorder = new CALayer
{
Frame = new CGRect(0.0f, element.HeightRequest - 1, this.Frame.Width, 1.0f),
BorderWidth = 2.0f,
BorderColor = element.LineColor.ToCGColor()
};
textField.Layer.AddSublayer(bottomBorder);
textField.Layer.MasksToBounds = true;
}
but this is what I'm getting

XNA 4.0 Camera and object handling on screen

For developing a side-scrolling platform 2D game I want to implement a moving camera class, the reason of using the class instead of moving the whole map is that I'll have to use too many objects at once witch will cause a lag. I cannot let that happen.
There's a nice algorithm for handling the camera, when player is moving further than the width of the screen then camera moves on players direction until he is once again in the middle of the screen, I've been working several days for making this algorithm work however there's been no success.
// Main
public class Camera
{
protected float _zoom;
protected Matrix _transform;
protected Matrix _inverseTransform;
//The zoom scalar (1.0f = 100% zoom level)
public float Zoom
{
get { return _zoom; }
set { _zoom = value; }
}
// Camera View Matrix Property
public Matrix Transform
{
get { return _transform; }
set { _transform = value; }
}
// Inverse of the view matrix,
// can be used to get
// objects screen coordinates
// from its object coordinates
public Matrix InverseTransform
{
get { return _inverseTransform; }
}
public Vector2 Pos;
// Constructor
public Camera()
{
_zoom = 2.4f;
Pos = new Vector2(0, 0);
}
// Update
public void Update(GameTime gameTime)
{
//Clamp zoom value
_zoom = MathHelper.Clamp(_zoom, 0.0f, 10.0f);
//Create view matrix
_transform = Matrix.CreateScale(new Vector3(_zoom, _zoom, 1)) *
Matrix.CreateTranslation(Pos.X, Pos.Y, 0);
//Update inverse matrix
_inverseTransform = Matrix.Invert(_transform);
}
}
This is the camera class I made for handling the screen, it's main purpose is to resize the screen, more precisely to zoom in and out whenever I want to change my screen, (Title screen, Playing screen, Game over, and like that.)
Moving the camera is quite simple with keys, like this.
if (keyState.IsKeyDown(Keys.D))
Cam.Pos.X -= 20;
if (keyState.IsKeyDown(Keys.A))
Cam.Pos.X += 20;
if (keyState.IsKeyDown(Keys.S))
Cam.Pos.Y -= 20;
if (keyState.IsKeyDown(Keys.W))
Cam.Pos.Y += 20;
And ofc. the drawing method witch apply the camera.
spriteBatch.Begin(SpriteSortMode.Texture, BlendState.AlphaBlend, null, null, null, null, Cam.Transform);
Here comes the part when I stop, so what I want to do is make something like 2 2D rooms. By Room I mean the place where I usually place objects. like this "Vector2(74, 63)" So I want to create a place where I could draw items that would stick to the screen and wouldn't move, and make the screen bounds that would make my algorithm to work, witch will be always on screen and as an addition it will check if one of the borders of the screen "room" reaches the certain coordinates of the map "room".
I think that the reason for that would be obvious because I don't want player to move camera outside the map when he reaches the wall, otherwise the player would already see a part of the next map where he will be transformed.
The reason of drawing both maps next to each other is again to reduce the loading time so player wouldn't have to wait for playing the next map.
Alright, so I've run into more troubles than I expected so I'll add extra information and will start with the player class:
// Main
public class Player
{
public Texture2D AureliusTexture;
public Vector2 position;
public Vector2 velocity;
public Vector2 PosForTheCam; // Variable that holds value for moving the camera
protected Vector2 dimensions;
protected CollisionPath attachedPath;
const float GRAVITY = 18.0f;
const float WALK_VELOCITY = 120f;
const float JUMP_VELOCITY = -425.0f;
// Constructor
public Player()
{
dimensions = new Vector2(23, 46);
position = new Vector2(50, 770);
}
public void Update(float deltaSeconds, List<CollisionPath> collisionPaths)
{
#region Input handling
KeyboardState keyState = Keyboard.GetState();
if (keyState.IsKeyDown(Keys.Left))
{
velocity.X = -WALK_VELOCITY;
}
else if (keyState.IsKeyDown(Keys.Right))
{
velocity.X = WALK_VELOCITY;
}
else
{
velocity.X = 0;
}
if (attachedPath != null && keyState.IsKeyDown(Keys.Space))
{
velocity.Y = JUMP_VELOCITY;
attachedPath = null;
}
velocity.Y += GRAVITY;
#endregion
#region Region of handling the camera based on Player
PosForTheCam.X = velocity.X;
#endregion
#region Collision checking
if (velocity.Y >= 0)
{
if (attachedPath != null)
{
position.X += velocity.X * deltaSeconds;
position.Y = attachedPath.InterpolateY(position.X) - dimensions.Y / 2;
velocity.Y = 0;
if (position.X < attachedPath.MinimumX || position.X > attachedPath.MaximumX)
{
attachedPath = null;
}
}
else
{
Vector2 footPosition = position + new Vector2(0, dimensions.Y / 2);
Vector2 expectedFootPosition = footPosition + velocity * deltaSeconds;
CollisionPath landablePath = null;
float landablePosition = float.MaxValue;
foreach (CollisionPath path in collisionPaths)
{
if (expectedFootPosition.X >= path.MinimumX && expectedFootPosition.X <= path.MaximumX)
{
float pathOldY = path.InterpolateY(footPosition.X);
float pathNewY = path.InterpolateY(expectedFootPosition.X);
if (footPosition.Y <= pathOldY && expectedFootPosition.Y >= pathNewY && pathNewY < landablePosition)
{
landablePath = path;
landablePosition = pathNewY;
}
}
}
if (landablePath != null)
{
velocity.Y = 0;
footPosition.Y = landablePosition;
attachedPath = landablePath;
position.X += velocity.X * deltaSeconds;
position.Y = footPosition.Y - dimensions.Y / 2;
}
else
{
position = position + velocity * deltaSeconds;
}
}
}
else
{
position += velocity * deltaSeconds;
attachedPath = null;
}
#endregion
}
}
So I state it clear that I asked my friend to do most of it because I wanted to handle the gravity and the slopes so we made it work similar like in Unity. And he happened to know how to do that.
And so I'll add the Update method that handles the camera from the Main Class.
MM.Update(gameTime); // Map Managher update function for map handling
Cam.Update(gameTime); // Camera update
Cam.Zoom = 2.4f; // Sets the zoom level for the title screen
// Takes the start position for camera in map and then turns off the update
// so the camera position can be changed. Else it would just keep an infinite
// loop and we couldn't change the camera.
if (StartInNewRoom)
{
Cam.Pos = MM.CameraPosition; // Applys the camera position value from the map manager class
StartInNewRoom = false;
}
I am unsure how to handle the camera, like I used your method and the result often ended up that camera moves by itself or it doesn't move at all.
If you don't want objects to move with the camera like a HUD you need a second spriteBatch.Begin() without your camera matrix which you draw after your actual scene.
To make the camera not move out of the map you could use some kind of collision detection. Just calculate the right border of your camera. It depends where the origin of your camera is.
Is your camera matrix working like this? Because the position should be negative or it will move in the wrong direction.
This is how mine looks like.
return Matrix.CreateTranslation(new Vector3(-camera.position.X, -camera.position.Y, 0)) *
Matrix.CreateRotationZ(Rotation) * Matrix.CreateScale(Zoom) *
Matrix.CreateTranslation(new Vector3(Viewport.Width * 0.5f, Viewport.Height * 0.5f, 0));
Viewport.Width/Height * 0.5 centers you camera.
You can also apply this behind your Pos.X/Y
To Camera follows player
public void Update(Player player)
{
//Clamp zoom value
_zoom = MathHelper.Clamp(_zoom, 0.0f, 10.0f);
//Create view matrix
_transform = Matrix.CreateScale(new Vector3(_zoom, _zoom, 1)) *
Matrix.CreateTranslation(player.Pos.X, player.Pos.Y, 0);
//Update inverse matrix
_inverseTransform = Matrix.Invert(_transform);
}

How to detect ListView is scrolling up or down

Is there a way to detect that ScrollViwer of ListView is in scrolling mode and stopped scrolling. In windows phone 8.1 ListView we can not get reference of the scrollviewer.
Any one done it in windows phone 8.1 WinRT app?
Once the ListView is Loaded you can get the ScrollViewer like this:
var sv = (ScrollViewer)VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(this.ListV, 0), 0);
Edit
As Romasz suggested, once you get the ScrollViewer, you can use its ViewChanged event, to monitor when it is scrolling and when it stops.
Also, here's the generic extension method that I use for traversing the visual tree:
// The method traverses the visual tree lazily, layer by layer
// and returns the objects of the desired type
public static IEnumerable<T> GetChildrenOfType<T>(this DependencyObject start) where T : class
{
var queue = new Queue<DependencyObject>();
queue.Enqueue(start);
while (queue.Count > 0) {
var item = queue.Dequeue();
var realItem = item as T;
if (realItem != null) {
yield return realItem;
}
int count = VisualTreeHelper.GetChildrenCount(item);
for (int i = 0; i < count; i++) {
queue.Enqueue(VisualTreeHelper.GetChild(item, i));
}
}
}
To get the ScrollViewer using this methos, do this:
var sv = yourListView.GetChildrenOfType<ScrollViewer>().First();
You can find the ScrollViewer of your ListView by using VisualTreeHelper. For example like this:
// method to pull out a ScrollViewer
public static ScrollViewer GetScrollViewer(DependencyObject depObj)
{
if (depObj is ScrollViewer) return depObj as ScrollViewer;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = GetScrollViewer(child);
if (result != null) return result;
}
return null;
}
Once you have a ScrollViewer you can subscribe to its events:
GetScrollViewer(yourListView).ViewChanged += yourEvent_ViewChanged;
You must load data to listview before getting scrollview. If listview has empty row then scrollview you get will be null.

MT.Dialog FloatElement is not responsive

I've added a floatElement to a root section, but when running the app, it seems that the slider is kind of unresponsive. I have to press multiple times to move the slider.
RootElement root = new RootElement (title)
{
new Section("Weight")
{
new FloatElement(null, null, 0.5f);
}
};
The problem is both on my physical device and in the simulator - both running iOS 7.
Any clues?
Ok, I've got a solution (of sorts). I created my own FloatElement (using the Monodialog source from github) and used my own slider inside it. I borrowed a tip from here
http://www.mpatric.com/2009-04-15-more-responsive-sliders-on-the-iphone
to come up with this, which works, but does feel a bit hacky. Not sure why the behaviour has changed in iOS7 though.
public class Slidy : UISlider
{
private static int THUMB_SIZE = 10;
private static int EFFECTIVE_THUMB_SIZE = 20;
public Slidy(RectangleF r)
: base(r)
{
}
public override bool PointInside(PointF point, UIEvent uievent)
{
var bounds = this.Bounds;
bounds = RectangleF.Inflate(bounds, 25, 25);
return bounds.Contains(point);
}
public override bool BeginTracking(UITouch touch, UIEvent uievent)
{
var bounds = this.Bounds;
float thumbPercent = (this.Value - this.MinValue) / (this.MaxValue - this.MinValue);
float thumbPos = THUMB_SIZE + (thumbPercent * (bounds.Size.Width - (2 * THUMB_SIZE)));
var touchPoint = touch.LocationInView(this);
return (touchPoint.X >= (thumbPos - EFFECTIVE_THUMB_SIZE) &&
touchPoint.X <= (thumbPos + EFFECTIVE_THUMB_SIZE));
}
}

Displaying a fading balloon type message box

I need to have a balloon like message box that displays for a few seconds and then fades away (not disappears at once)
Please advise how to do this.
Thanks
Furqan
Try this:
Dim buttonToolTip As New ToolTip()
with buttonToolTip
.ToolTipTitle = "Button Tooltip"
.UseFading = True
.UseAnimation = True
.IsBalloon = True
.ShowAlways = True
.AutoPopDelay = 5000
.InitialDelay = 1000
.ReshowDelay = 500
.IsBalloon = True
.SetToolTip(Button1, "Click me to execute.")
End With
EDITED:
If you need a fading MessageBox, you can do this:
create a form that accepts a status and a text in constructor
swtich on status drawing correct icon and place text on form
create a timer and on Tick event check if it's time to close
if it's time to close call FadeForm method
Example:
public enum Status
{
None,
Error,
Question,
Warning,
Info
}
public class FadingForm: Form
{
dt: TDateTime;
public FadingForm(Status status, string msg)
{
this.lbl.Text = msg; // I imagine you have a Label named lbl
switch (status)
{
case Warning:
img.Image = warning; // I imagine you have a PictureBox named img
break;
case ...
}
dt = DateTime.Now;
tmr.Enabled = true;
}
public void Tmr_Tick()
{
if (DateTime.Now - dt) > limit
{
FadeForm(10); //Just an example
Close();
}
}
public void FadeForm(byte NumberOfSteps)
{
float StepVal = (float)(100f / NumberOfSteps);
float fOpacity = 100f;
for (byte b = 0; b < NumberOfSteps; b++)
{
this.Opacity = fOpacity / 100;
this.Refresh();
fOpacity -= StepVal;
}
}
}
I think this behavior depends on users windows settings, if you want to achieve this you can code a balloon message your self and decrease its opacity before closing it completely.