I have a BoxView that I want to change the color of when the user taps it. I created a BoxView called tapView and set the GestureRecognizer like so:
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += (s, e) => {
// handle the tap
OnTapGestureRecognizerTapped(s, e);
};
tapView.GestureRecognizers.Add(tapGestureRecognizer);
and my method to handle the tap:
void OnTapGestureRecognizerTapped(object sender, EventArgs args)
{
var box = (BoxView)sender;
box.Color = Color.Red;
}
However this doesn't actually change the color on the Tap. Debugging and stepping through the code it does actually update the BoxView color in the code but not on the screen. What do I need to do to make this actually update the color when touched?
Try this solution, assuming you give your BoxView the following property in your XAML x:Name="myBox"
//This code betlow the page InitializeComponent call
var boxTapHandler = new TapGestureRecognizer();
boxTapHandler.Tapped += ChangeColor;
myBox.GestureRecognizers.Add(boxTapHandler);
Change color method, similar, though referencing the BoxView by name
private void ChangeColor(object sender, EventArgs args)
{
myBox.Color = Color.red;
}
So I discovered as standalone code this works ok, but in my MVVM app it does not. I wound up creating a box on top and changing the opacity on a tap worked just fine.
Related
I want to make a button that has a small icon (from FontAwesome) and text on it in my Xamarin app. I know I can just make a button but the problem is that I will require two fonts (the standard font for text and FontAwesome for the icon). Would anyone happen to know how I can do this, or if there is another way to achieve what I want?
Thanks!
As the json mentioned, I just made a simple implementation.
Create a new class inherit from Label, set FormattedText to combine the string(standard and icon), and add tap gesture on it .
public class MyLabel : Label
{
public delegate void MyHandler(object sender, EventArgs e);
public event MyHandler myEvent;
public MyLabel(string _myIcon, string _myText)
{
//build the UI
FormattedString text = new FormattedString();
text.Spans.Add(new Span { Text = _myIcon ,FontFamily= "FontAwesome5Free-Regular" });
text.Spans.Add(new Span { Text = _myText, TextColor = Color.Red ,BackgroundColor = Color.Blue });
FormattedText = text;
//tap event
TapGestureRecognizer tap = new TapGestureRecognizer();
tap.Tapped += (sender,e) => {
myEvent(sender,e);
};
}
}
Usage
MyLabel label = new MyLabel("", "test");
label.myEvent += (sener,e) =>
{
//do something when tapping
};
Content = label;
For how to integrate FontAwesome in Xamarin.Forms ,refer to
https://montemagno.com/xamarin-forms-custom-fonts-everywhere/.
I know that I can make a Label clickable by using TapGesture. How can I give a highlight effect when the user is tapping it? (Either changing the Label's color or changing the Background Color just like when the user taps the Toolbar Items)
You could simulate the effect with a TapGestureRecognizer by just changing the color of your label in your tapped method and back at the end.
private void OnTapped(object sender, EventArgs e)
{
var label = sender as Label;
label.TextColor = Color.Gray;
//Do Something
label.TextColor = Color.Black;
}
Although, styling a button might work better to handle the effect for you.
Here is a fix to Nick Pepper's answer, to properly restore color on UI thread.
private void OnTapped(object sender, EventArgs e)
{
var label = sender as Label;
label.TextColor = Color.Gray;
Run.Task( () => {
// Now we are on a background thread, can take as long as we want.
// ... Do Something ...
Device.BeginInvokeOnMainThread( () => {
// Now we are back on main thread, can change UI.
label.TextColor = Color.Black;
});
});
}
HOWEVER this won't change color to Gray until OnTapped fires - which is NOT the instant that user pushes down. So still isn't what user asked for.
Changing the color as soon as the user starts pushing is more involved. Might need to use Touch Tracking API.
OR use Visual State Manager.
I would like to add a button dynamically in StackLayout when "add" button is clicked. I wrote stacklayoutname.children.add(button), it does not giving me the thing i am looking for.
In xaml:
<StackLayout x:Name="layout">
<Button Text="add" Clicked="Addbutton"/>
</StackLayout>
In code:
private void Addbutton(object sender, EventArgs e)
{
var layout = new StackLayout();
var btn = new Button { Text = "New button", FontSize = 30, TranslationY = 30 };
this.Content = layout;
layout.Children.Add(btn);
}
It is giving only new button and add button is disappearing, but I want whenever we click on add button it should give number of new button equal to the number of clicks on add button.
Since you already have a StackLayout, there's no need to add a new one, because it replaces the old one if you do. The following will add a button to the StackLayout on every button click.
// Define a field for StackLayout
StackLayout parent;
public void Addbutton(object sender, EventArgs e)
{
// Define a new button
Button newButton = new Button { Text = "New Button" };
// Creating a binding
newButton.SetBinding(Button.CommandProperty, new Binding ("ViewModelProperty"));
// Set the binding context after SetBinding method calls for performance reasons
newButton.BindingContext = viewModel;
// Set StackLayout in XAML to the class field
parent = layout;
// Add the new button to the StackLayout
parent.Children.Add(newButton);
}
For more information about Binding, check out BindableObject Class and Data Binding Basics.
I have a list on images in a Pivot control. If you touch an image, it navigates to another view. If if flick through a new pivot and touch the image meanwhile, it navigates.
I noticed the Facebook app or the native photo albums don't have this bug.
Any idea ?
edit: the code :
Image img = new Image();
Delay.LowProfileImageLoader.SetUriSource(img, new Uri(adViewModel.Photos[k].ThbUrl));
img.Width = 150;
img.Tag = k;
img.Height = 150;
img.MouseLeftButtonDown += new MouseButtonEventHandler(launch_Diapo);
Grid.SetRow(img, i);
Grid.SetColumn(img, j);
PhotosGrid.Children.Add(img);
If you can show your code we can probably provide a more specific answer.
However:
I'm guessing you're using MouseButtonLeftDown or similar to detect the touching of the image. Rather than this, use the Tap gesture from the toolkit. This should prevent the issue you're having.
There is a possible alternative to disable the pivot gesture while you're touching the image, but depending on how you're using the image within the pivotItem this may end up preventing proper pivot navigation.
You can add the Tap event in code like this:
var gl = GestureService.GetGestureListener(img);
gl.Tap += new EventHandler<GestureEventArgs>(gl_Tap);
and the handler would be something like this. (but actually doing something useful-obviously.)
void gl_Tap(object sender, GestureEventArgs e)
{
MessageBox.Show("tapped");
}
Even I had a similar problem . What i did is ,check for MouseButtonLeftDown position and MouseButtonLeftUp position .If they are Equal navigate else do nothing .I will paste the code below.
Point temp;
void img_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
temp = e.GetPosition(null);
}
void img_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Point point = e.GetPosition(null);
if (point == temp)
{
this.NavigationService.Navigate(new Uri(...));
}
}
I have a wp7 with some buttons in the application bar.
When each button is pressed I change the menuItems of the application bar's menu.
After this, I want to automatically open the menu when an application bar button is pressed.
But it seems that the SDK doesn't allow me to do that.
Do you know any work around?
I was thinking, if the above is not possible, to simulate a user finger click at the bottom right corner of the screen to open the menu. Any ideas on that?
Thanx in advance
It's possible to change the Application Bar Menu Items in response to an Icon Button click as demonstrated in the code below.
There isn't a way to forcibly open (or close) the application bar through code through.
It also isn't possible to simulate a finger click on the application bar as this isn't part of the actual page. Note that even if possible any click would need to be in the top right or bottom left if the device was in a landscape orientation.
Here's some code which demonstrates changing the menu items:
public partial class MainPage : PhoneApplicationPage
{
private ApplicationBar appbar;
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
appbar = new ApplicationBar();
var ib1 = new ApplicationBarIconButton(new Uri("/images/one.png", UriKind.Relative)) { Text = "Option one" };
ib1.Click += new EventHandler(ShowMenuOption1);
var ib2 = new ApplicationBarIconButton(new Uri("/images/two.png", UriKind.Relative)) { Text = "Option two" };
ib2.Click += new EventHandler(ShowMenuOption2);
appbar.Buttons.Add(ib1);
appbar.Buttons.Add(ib2);
// Show menu option 1 as default
DisplayMenuOption1();
this.ApplicationBar = appbar;
}
private void DisplayMenuOption1()
{
appbar.MenuItems.Clear();
var itemA = new ApplicationBarMenuItem("AAAA");
var itemB = new ApplicationBarMenuItem("BBB");
appbar.MenuItems.Add(itemA);
appbar.MenuItems.Add(itemB);
}
private void DisplayMenuOption2()
{
appbar.MenuItems.Clear();
var itemC = new ApplicationBarMenuItem("CCCC");
var itemD = new ApplicationBarMenuItem("DDDD");
appbar.MenuItems.Add(itemC);
appbar.MenuItems.Add(itemD);
}
private void ShowMenuOption2(object sender, EventArgs e)
{
DisplayMenuOption2();
}
private void ShowMenuOption1(object sender, EventArgs e)
{
DisplayMenuOption1();
}
}
As far as I'm aware this capability has not been exposed as yet. It wasn't possible during beta and I've not noticed anything that's changed since that would allow it. You could always comment on the their suggestions forum or raise it on connect (vs/wpdt).