My apps is planned to allow orientation change, however, I have background images (in pivot control that allow user to change the background images) that does not want to change the orientation. How should i implement that?
thanks for advice.
You might be able to add a Rotation Transform dynamically to offset the rotation of the background image when the orientation changes, as below :-
private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
{
if (e.Orientation == PageOrientation.PortraitUp)
{
PivotBackground.RelativeTransform = null;
}
else
{
RotateTransform aRotateTransform = new RotateTransform();
aRotateTransform.CenterX = 0.5;
aRotateTransform.CenterY = 0.5;
aRotateTransform.Angle = 90;
PivotBackground.RelativeTransform = aRotateTransform;
}
}
The XAML is defined as :-
<controls:Pivot Title="MY APPLICATION">
<controls:Pivot.Background>
<ImageBrush ImageSource="/Back.jpg"
x:Name="PivotBackground">
</ImageBrush>
</controls:Pivot.Background>
</controls:Pivot>
Hope this helps.
Paul Diston
Related
How do I change the height of a Xamarin Forms ProgressBar in code? Am using Xamarin Forms V2.1.
.HeightRequest and .MinimumHeightRequest seem to have no effect. The default progress bar is so thin that it might not even be noticed.
.BackgroundColor does not seem to work either.
What am I missing here?
You need custom renderers for this:
First create a class for your custom progress bar:
public class CustomProgressBar :ProgressBar
{
public CustomProgressBar()
{
}
}
And then also add a new file for your custom progress bar renderer:
For iOS:
public class CustomProgressBarRenderer : ProgressBarRenderer
{
protected override void OnElementChanged(
ElementChangedEventArgs<Xamarin.Forms.ProgressBar> e)
{
base.OnElementChanged(e);
Control.ProgressTintColor = Color.FromRgb(182, 231, 233).ToUIColor();// This changes the color of the progress
}
public override void LayoutSubviews()
{
base.LayoutSubviews();
var X = 1.0f;
var Y = 10.0f; // This changes the height
CGAffineTransform transform = CGAffineTransform.MakeScale(X, Y);
Control.Transform = transform;
}
}
[EDIT: fixed code above as per comment]
For Android:
public class CustomProgressBarRenderer :ProgressBarRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ProgressBar> e)
{
base.OnElementChanged(e);
Control.ProgressTintList = Android.Content.Res.ColorStateList.ValueOf(Color.FromRgb(182, 231, 233).ToAndroid()); //Change the color
Control.ScaleY = 10; //Changes the height
}
}
I hope this helps you!
To make the progress bar thicker, you just have to change the ScaleY property of the ProgressBar.
For example:
This code
<ProgressBar Progress=".5"/>
<ProgressBar ScaleY="2" Progress=".5"/>
<ProgressBar ScaleY="5" Progress=".5"/>
Produces this
Note that you may need to adjust your margins accordingly.
<ProgressBar
BackgroundColor="White"
ProgressColor="#BCC7EF"
Progress="0.7">
<ProgressBar.ScaleY>
<OnPlatform
x:TypeArguments="x:Double"
iOS="2"
Android="1" />
</ProgressBar.ScaleY>
#BillF is correct basically
In the iOS renderer code try using
this.Control.Transform = transform;
instead of
this.Transform = transform;
I faced the same need and on the latest version of Visual Studio, 16.5.2 I figured out that to get a bigger horizontal bar you just need to set ScaleY within the progressbar declaration inside the xml.
To avoid glitches on Android and be sure that the progress bar is not overwhelming other elements I added a margin as you can see from the declaration here below.
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/progressBar1"
android:layout_below="#+id/message"
android:scaleY="8"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"/>
For me, the most simple solution is to use Xamarin.Forms.Visual.Material
Then in your XAML, in progress bar set HeightRequest property to what you want and use Visual property as Material.
i want to create a greeting card maker app for WP7, when a user double taps an image from a listbox, I want that selected image to fill a rectangle on the same page.
Im passing 50 images into the list box like this:
public GCM()
{
InitializeComponent();
var articles = new List<Article>();
for (byte i = 1; i <= 20; i++)
{
Article article = new Article() { Name = "name"+i, ImagePath = "Assets/Images/Backgrounds/"+i+".jpg" };
articles.Add(article);
}
listBox1.DataContext = articles;
}
and its working fine, now heres an xml snippet:
<Rectangle Fill="#FFF4F4F5" Margin="28,24,30,148" Stroke="Black" Name="rect1" />
................(more code here).........................
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10" >
<Image Name="bgs" Source="{Binding ImagePath}" Height="90" Width="90" DoubleTap="Load_BG" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
how can i fill the rectangle with the tapped image? this code (below) sets the string null everytime, no matter which image i select, although to my knowledge each has a different name and it should give different names for different images. I will use the name of the image to fill the rectangle. What am i doing wrong?
private void Load_BG(object sender, System.Windows.Input.GestureEventArgs e)
{
string abc = sender.GetType().Name;
}
Please excuse me if the solution is obvious..this is my first app ever. Thank you!
sender parameter should contains the control that triggered the event, in this case Image control. Try to cast it to Image type, then you can get the information you needed from Source property :
private void Load_BG(object sender, System.Windows.Input.GestureEventArgs e)
{
Image img = (Image)sender;
//do something with img.Source here
}
so heres the solution, it works now :)
private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var img = listBox1.SelectedItem as Article;
ImageBrush imgBrush = new ImageBrush();
imgBrush.ImageSource = new BitmapImage(new Uri(img.ImagePath, UriKind.RelativeOrAbsolute));
rect1.Fill = imgBrush;
}
I need an image that can follow my finger (mouse) on the screen... the following code works fine on Portrait Mode, but it get's completely mess up on Landscape Mode, has anybody been across to this?
<Image Height="68" HorizontalAlignment="Left" Margin="872,388,0,0" Name="imgStarPoint" Stretch="Fill" VerticalAlignment="Top" Width="54" Source="/GetMousePoint;component/StarT.png" ManipulationCompleted="imgStarPoint_ManipulationCompleted">
<i:Interaction.Behaviors>
<el:MouseDragElementBehavior x:Name="imgStar"/>
</i:Interaction.Behaviors>
</Image>
and code behind:
void Touch_FrameReported(object sender, TouchFrameEventArgs e)
{
var PrimaryPoint = e.GetPrimaryTouchPoint(null);
imgStar.X = PrimaryPoint.Position.X;
imgStar.Y = PrimaryPoint.Position.Y;
txt1.Text = PrimaryPoint.Position.X + "." + PrimaryPoint.Position.Y;
}
Does anybody has a way to set the image on my finger tip on Landscape Mode?
EDIT:
Ok, for some reason I though you were using WP Toolkit's Gesture listener which will report the correct X any Y in each orientation mode. In your case you need to detect which orientation mode you are in and do the necessary adjustments.
It seems like when orientation is in landscape the axis are switched. When in landscape-left mode the X axis is inverted and in landscape-right mode the Y axis is inverted. Following code should fix your problem:
bool _switchAxis;
bool _invertX ;
bool _invertY;
private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e) {
_switchAxis = (e.Orientation | PageOrientation.LandscapeLeft | PageOrientation.LandscapeRight) == (PageOrientation.LandscapeLeft | PageOrientation.LandscapeRight);
_invertX = e.Orientation == PageOrientation.LandscapeLeft;
_invertY = e.Orientation == PageOrientation.LandscapeRight;
}
private void Touch_FrameReported(object sender, System.Windows.Input.TouchFrameEventArgs e) {
var width = Application.Current.Host.Content.ActualWidth;
var height = Application.Current.Host.Content.ActualHeight;
var primaryPoint = e.GetPrimaryTouchPoint(null);
if (_switchAxis) {
if (_invertY) imgStar.X = height - primaryPoint.Position.Y; else imgStar.X = primaryPoint.Position.Y;
if (_invertX) imgStar.Y = width - primaryPoint.Position.X; else imgStar.Y = primaryPoint.Position.X;
} else {
imgStar.X = primaryPoint.Position.X;
imgStar.Y = primaryPoint.Position.Y;
}
}
You need to add OrientationChanged event to your page xaml:
<phone:PhoneApplicationPage
<!-- ... -->
OrientationChanged="PhoneApplicationPage_OrientationChanged"
/>
In Landscape mode, a visible application bar and system tray will mess up X for you.
If you have an application bar, set its mode to minimized
ApplicationBar.Mode = ApplicationBarMode.Minimized
You also need to hide the system tray to avoid manual adjustments on X. Do that on the page Loaded event
Xaml:
<phone:PhoneApplicationPage
<!-- stuff -->
Loaded="PhoneApplicationPage_Loaded"
/>
Code behind:
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e) {
SystemTray.IsVisible = false;
}
Also you would want to deduct image.Width/2 from X and image.Height/2 from Y to make it exactly at the center of your finger tip.
imgStar.X = PrimaryPoint.Position.X - (img.Width/2);
imgStar.Y = PrimaryPoint.Position.Y - (img.Height/2);
That should fix the problem.
I have added 10 images in a stackpanel horizontally which is inside a scrollviewer. When user swipe the page ,the scrollviewer stops at certain position, if the scroll stops in the middle of 2 images like the first image shown below i want to set the image with number 3 to be automatically scroll and fit with the left side of the screen like in the second image
for (int i = 0; i <= 9; i++)
{
Uri uri = new Uri("http://d1mu9ule1cy7bp.cloudfront.net//catalogues/47/pages/p_" + i + "/thump.jpg");
ImageSource img1 = new BitmapImage(uri);
Image rect = new Image { RenderTransform = new TranslateTransform() };
rect.Source = img1;
stack.Children.Add(rect);
}
XAML:
<Grid x:Name="LayoutRoot" Width="480" Background="Transparent" Margin="0,-33,0,0" Height="800">
<ScrollViewer HorizontalContentAlignment="Left" HorizontalAlignment="Left" Name="scroll" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Visible">
<StackPanel Name="stack" Width="Auto" Orientation="Horizontal" HorizontalAlignment="Left" >
</StackPanel>
</ScrollViewer>
</Grid>
The first thing you need to do is detect which item is overlapping the side of the screen. To do this, iterate over each item within the StackPanel and determine their location relative to some other element that has a fixed location on screen.
To do this, I use the following extension method:
/// <summary>
/// Gets the relative position of the given UIElement to this.
/// </summary>
public static Point GetRelativePosition(this UIElement element, UIElement other)
{
return element.TransformToVisual(other)
.Transform(new Point(0, 0));
}
i.e. for each item call the following;
Point position = stackPanelItem.GetRelativePosition(someFixedElement);
Using the location of each item, you should be able to work out which one overlaps the screen.
You then need to calculate by how much you need to scroll in order to ensure that your item is fully visible, then use ScrollViewer.ScrollToVerticalOffset to scroll to that location.
This probably isn't the nicest solution and I am sure there is a better way to achieve this but you could use the following :-
XAML :-
<ListBox x:Name="MyListBox"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollBarVisibility="Visible">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
C# :-
DispatcherTimer myTimer = new DispatcherTimer();
// Constructor
public MainPage()
{
InitializeComponent();
for (int i = 0; i < 10; i++)
{
MyListBox.Items.Add(new Button()
{
Content = i.ToString(),
Width = 200,
Height = 100,
});
MyListBox.MouseMove += new MouseEventHandler(MyListBox_MouseMove);
}
myTimer.Interval = TimeSpan.FromSeconds(1);
myTimer.Tick += new EventHandler(myTimer_Tick);
}
private void myTimer_Tick(object sender, EventArgs e)
{
myTimer.Stop();
SnapFirstItem();
}
private void MyListBox_MouseMove(object sender, MouseEventArgs e)
{
myTimer.Stop();
myTimer.Start();
}
private void SnapFirstItem()
{
foreach (Button currentButton in MyListBox.Items)
{
bool visible = MyListBox.TestVisibility(currentButton, System.Windows.Controls.Orientation.Horizontal, true);
if (visible)
{
MyListBox.ScrollIntoView(currentButton);
break;
}
}
}
The TestVisibility extension method is from the following :-
http://blogs.msdn.com/b/ptorr/archive/2010/10/12/procrastination-ftw-lazylistbox-should-improve-your-scrolling-performance-and-responsiveness.aspx
i want to play video in my app. I see around but nothing helped me. I ask the user if he wants to listen to his phone music. If clicks ok the music continue playing, if not then the music stop. That is ok from now. Now, my problem is: I create a grid to use it like popup with width and height and so on.. When this popup appears the music stops. This is why can not certify my app in marketplace.
Here is a little code: i believe is easy to understand... Please help!
public void new_grid(int v)
{
Grid gr = new Grid();
gr.Background = new SolidColorBrush(Colors.Cyan);
gr.Opacity = 1.0;
gr.Width = 400;
gr.Height = 600;
// Create a white border.
Border border = new Border();
border.BorderBrush = new SolidColorBrush(Colors.White);
border.BorderThickness = new Thickness(7.0);
MediaElement video_ship = new MediaElement();
//video_ship.AutoPlay = false;
video_ship.Width = 400;
video_ship.Height = 600;
video_ship.VerticalAlignment = VerticalAlignment.Top;
video_ship.HorizontalAlignment = HorizontalAlignment.Left;
if (v == 1)
{
video_ship.Source = new Uri("videos/Lost_Ship.wmv", UriKind.RelativeOrAbsolute);
//video_ship.Play();
gr.Children.Add(video_ship);
}
else if (v == 2)
{
//video_ship.Source = "videos/Lost_Ship.wmv";
video_ship.Source = new Uri("videos/you_are_on_fire.wmv", UriKind.RelativeOrAbsolute);
//video_ship.Name = "fire";
//video_ship.Play();
gr.Children.Add(video_ship);
}
else if (v == 3)
{
//video_ship.SourceName = "videos/Lost_Ship.wmv";
video_ship.Source = new Uri("videos/EscapeShip.wmv", UriKind.RelativeOrAbsolute);
//video_ship.Name = "escape";
//video_ship.Play();
gr.Children.Add(video_ship);
}
I send a variable v to select one of my videos..I set the videos to Build Action Content
Any ideas what to do? or something different than this?
I want only to play the video ..Video does not have music ..or sound effect..
I tested it and it works. You want to popup video when you call event. so you shoud put grid inside file xaml code and it is hidden.
This is my test
on xaml
<Grid x:Name="LayoutRoot" Background="Transparent">
<Image Source="BackgroundMain3.jpg" Stretch="UniformToFill"/>
<Grid Height="400" Width="600" x:Name="playvideo" Visibility="Collapsed">
<MediaElement x:Name="element"/>
</Grid>
<Button Content="Button" Height="72" HorizontalAlignment="Left" Margin="129,684,0,0" Name="button1" VerticalAlignment="Top" Width="160" Click="button1_Click" />
</Grid>
on xaml.cs
private void button1_Click(object sender, RoutedEventArgs e)
{
poupup(3);
playvideo.Visibility = Visibility.Visible;
playvideo.Opacity = 0.8;
element.MediaOpened += new RoutedEventHandler(element_MediaOpened);
}
void element_MediaOpened(object sender, RoutedEventArgs e)
{
element.Play();
}
public void poupup(int v)
{
if (v == 1)
{
element.Source = new Uri("videos/Lost_Ship.wmv", UriKind.RelativeOrAbsolute);
}
else if (v == 2)
{
element.Source = new Uri("videos/you_are_on_fire.wmv", UriKind.RelativeOrAbsolute);
}
else if (v == 3)
{
element.Source = new Uri("YouTube.mp4", UriKind.RelativeOrAbsolute);
}
}