I added a logout button to the FlyoutFooter of the shell. After clicking it, it takes a certain waiting time to connect to the server, so I need to add an ActivityIndicator in the flyout.
<Shell.FlyoutFooter>
<Grid>
<Button Text="Logout"
Clicked="Button_Clicked"/>
</Grid>
</Shell.FlyoutFooter>
How can I add it there?
You can use FlyoutContent property:
<Shell.FlyoutFooter>
<Grid>
<Button Text="Logout"
Clicked="Button_Clicked"/>
</Grid>
</Shell.FlyoutFooter>
private async void Button_Clicked(object sender, EventArgs e)
{
var grid = new Grid();
grid.Children.Add(new ActivityIndicator()
{
IsRunning = true,
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Center
});
Current.FlyoutContent = grid;
await Task.Delay(5000);
FlyoutContent = null;
}
Related
I use SearchBar to search from listView and I have other controls
but when page load just SearchBar appear and other controls disappear
like this image
and when search then select from listView the disappeared controls appears
like this image
my xaml code :
<StackLayout>
<SearchBar x:Name="search_trade"
TextChanged="search_trade_TextChanged"
/>
<ListView x:Name="list" ItemSelected="list_ItemSelected" >
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}" ></TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Editor x:Name="edit_trade"
FontSize="14"/>
</StackLayout>
my c# code :
private void search_trade_TextChanged(object sender, TextChangedEventArgs e)
{
if (search_trade.Text.Trim()==string.Empty)
{
list.IsVisible = false;
}
list.IsVisible = true;
if (string.IsNullOrEmpty(e.NewTextValue))
{
list.ItemsSource = tempdata;
}
else
{
list.ItemsSource = tempdata.Where(x => x.Name.ToLower().StartsWith(e.NewTextValue));
}
}
private void list_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = (Contacts)e.SelectedItem;
edit_trade.Text = item.Name.ToString();
search_trade.Text = "";
list.IsVisible = false;
edit_trade.IsReadOnly = true;
}
code c# that I initially set the ItemsSource :
public Anti_biotic()
{
InitializeComponent();
active();
years_months();
frame_view.IsVisible = false;
trade();
}
private void trade()
{
tempdata = new List<Contacts>
{
new Contacts() { Name = "Amoclawin228.5mg/5mlsusp60ml"},
new Contacts() { Name = "Amoclawin 457mg / 5ml susp 60 ml"},
new Contacts() { Name = "Amoflux 250 mg susp 100 ml"},
};
}
how can I solve this issue?
you are not assigning the ListView's ItemsSource when the page loads. If the ListView doesn't have any data then it won't display anything
public Anti_biotic()
{
InitializeComponent();
active();
years_months();
frame_view.IsVisible = false;
// this method creates tempdata but doesn't do anything with it
trade();
// add this
list.ItemsSource = tempdata;
}
I have installed Xamarin.Forms.Googlemaps 2.3.0.But I can see blank control in Android with text "Xamarin.Forms.GoogleMaps" and in iOS, nothing.
Where am i going wrong ?
In Androidmanifest, added:-
<meta-data android:name="com.google.android.geo.API_KEY" android:value="API_KEY"/>
In xaml,namespace is:-
xmlns:gmap="clr-namespace:Xamarin.Forms.GoogleMaps;assembly=Xamarin.Forms.GoogleMaps"
Control is:-
<gmap:Map x:Name="map"
Grid.Row="1"
HasZoomEnabled="True"
HeightRequest="{x:Static local:AppConstants.ActivityLogGfxContainerSize}"
InitialCameraUpdate="-23.68, -46.87, 13, 30, 60"
IsShowingUser="True"
MapLongClicked="map_MapLongClicked"
VerticalOptions="FillAndExpand"
WidthRequest="{x:Static local:AppConstants.PadThird}" />
in xaml.cs:-
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
this.locationViewModel = viewModel as LocationControlViewModel;
Check.IsNotNull(locationViewModel);
map.MyLocationEnabled = true;
map.MoveToRegion(Xamarin.Forms.GoogleMaps.MapSpan.FromCenterAndRadius(new Xamarin.Forms.GoogleMaps.Position(this.locationViewModel.Latitude, this.locationViewModel.Longitude), Xamarin.Forms.GoogleMaps.Distance.FromMiles(1)));
}
private async void map_MapLongClicked(object sender, Xamarin.Forms.GoogleMaps.MapLongClickedEventArgs e)
{
this.locationViewModel.Latitude = e.Point.Latitude;
this.locationViewModel.Longitude = e.Point.Longitude;
Xamarin.Forms.GoogleMaps.Pin pin = new Xamarin.Forms.GoogleMaps.Pin
{
Type = Xamarin.Forms.GoogleMaps.PinType.Place,
Position = new Xamarin.Forms.GoogleMaps.Position(this.locationViewModel.Latitude, this.locationViewModel.Longitude),
Label = "test"
};
map.Pins.Clear();
map.Pins.Add(pin);
map.MoveToRegion(Xamarin.Forms.GoogleMaps.MapSpan.FromCenterAndRadius(new Xamarin.Forms.GoogleMaps.Position(this.locationViewModel.Latitude, this.locationViewModel.Longitude), Xamarin.Forms.GoogleMaps.Distance.FromMiles(1)));
var stream = await map.TakeSnapshot();
}
I am creating a window, in which click on save communicate with database and save data in database. I want to show progress image on click on save until data is not saved in database. I have set the visibility of image to true but still that progress image is not visible.
I have done following code...
In xml file..
<TextBox x:Name="txt_Comment" VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" AcceptsReturn="True" MaxLength="5000" Margin="2,2,2,0"></TextBox>
<WrapPanel Grid.Row="1" HorizontalAlignment="Center" Margin="10,-15,0,0" VerticalAlignment="Center">
<Button x:Name="btn_Ok" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" Click="btn_Save_Click" Height="25" Width="55">Save</Button>
<Button x:Name="btn_Cancel" Margin="10,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" Height="25" Width="55" Content="Cancel" Click="btn_Cancel_Click" >
</Button>
</WrapPanel>
<Grid Grid.RowSpan="2" Background="Black" Opacity="0.25" Name="LoadingAdorner" Visibility="Hidden"/>
<Border Width="400" Grid.RowSpan="2" Opacity="1" Height="180" Visibility="Hidden" HorizontalAlignment="Center" VerticalAlignment="Center" CornerRadius="2" x:Name="loaderBorder">
<Border.Background>
<LinearGradientBrush EndPoint="1,1" StartPoint="0,0" >
<GradientStop Color="#EBF6FA" Offset="0.3"/>
<GradientStop Color="#b7d9e5" Offset="1.0"/>
</LinearGradientBrush>
</Border.Background>
<Border.Effect>
<DropShadowEffect BlurRadius="5" Color="#FFB0B0B0" ShadowDepth="3" />
</Border.Effect>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition/>
<RowDefinition Height="95"/>
</Grid.RowDefinitions>
<Controls:LoadingAnimation Grid.Row="1" HorizontalAlignment="Center" FontWeight="Bold" LoadingText="Loading..." VerticalAlignment="Center" />
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" FontFamily="Arial" Foreground="#647883" FontSize="14" Grid.Row="2" Text="Saving..."></TextBlock>
</Grid>
</Border>
</Grid>
In code behind page..
BackgroundWorker worker = new BackgroundWorker { WorkerSupportsCancellation = true };
worker.DoWork += delegate(object sender1, DoWorkEventArgs e1)
{
CurrentDispatcher.Invoke(
new Action(() =>
{
if (!string.IsNullOrEmpty(txt_Comment.Text))
{
LoadingAdorner.Visibility = Visibility.Visible;
loaderBorder.Visibility = Visibility.Visible;
using (Entities DB = new Entities(settings.LinqConnection))
{
if (txt_Comment.Text.Length > 1000)
{//In this case loading image is visible
MessageBox.Show("Comment is too large.", "Alert !", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
var comment = DB.Table1.Create();//Here loading image is not visible.
comment.value = txt_Comment.Text;
comment.Date = DateTime.Now;
comment.ModifiedBy = settings.CurrentUID;
DB.Table1.Add(comment);
DB.SaveChanges();
}
}
}),
DispatcherPriority.Normal);
};
worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
this.DialogResult = true;
this.Close();
LoadingAdorner.Visibility = Visibility.Collapsed;
loaderBorder.Visibility = Visibility.Collapsed;
};
worker.RunWorkerAsync();
When messagebox is visible than loading image is visible, but when data is saving in database then loading image is not visible.
This is how i would have done in such situation :
Create delegate to update your visibility and corresponding method
Wrap your anonymous function in a function compatible with doWork event
Create a new delegate and call the update method using dispatcher.BeginInvoke() when you need to update visibility.
private delegate void UpdateVisibilityDelegate(Visibility visibility);
private void UpdateVisiblity(Visibility visibility)
{
//LoadingAdorner.Visibility = visibility;
//loaderBorder.Visibility = visibility;
}
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
// Your Action() code here
// Change the visibility using this method
Dispatcher.CurrentDispatcher.BeginInvoke(new UpdateVisibilityDelegate(this.UpdateVisiblity), Visibility.Visible);
}
Move your using block out of CurrentDispatcher.Invoke() and put after this call.
BackgroundWorker worker = new BackgroundWorker { WorkerSupportsCancellation = true };
worker.DoWork += delegate(object sender1, DoWorkEventArgs e1)
{
CurrentDispatcher.Invoke(
new Action(() =>
{
if (!string.IsNullOrEmpty(txt_Comment.Text))
{
LoadingAdorner.Visibility = Visibility.Visible;
loaderBorder.Visibility = Visibility.Visible;
}
}),
DispatcherPriority.Normal);
using (Entities DB = new Entities(settings.LinqConnection))
{
if (txt_Comment.Text.Length > 1000)
{//In this case loading image is visible
MessageBox.Show("Comment is too large.", "Alert !", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
var comment = DB.Table1.Create();//Here loading image is not visible.
comment.value = txt_Comment.Text;
comment.Date = DateTime.Now;
comment.ModifiedBy = settings.CurrentUID;
DB.Table1.Add(comment);
DB.SaveChanges();
}
};
so this code works for me:
private void Button_Click(object sender, RoutedEventArgs e)
{
var worker = new BackgroundWorker { WorkerSupportsCancellation = true };
worker.DoWork += delegate (object sender1, DoWorkEventArgs e1)
{
Dispatcher.Invoke(
new Action(() =>{testCtl.Visibility = Visibility.Visible;}),
System.Windows.Threading.DispatcherPriority.Normal);
Task.Delay(3000).Wait();
};
worker.RunWorkerCompleted += delegate (object s, RunWorkerCompletedEventArgs args)
{
testCtl.Visibility = Visibility.Collapsed;
};
worker.RunWorkerAsync();
}
I basically want to create a hyperlink in Xamarin.Forms using the label class. Basically, I want to following link to take the user to google.com in a web browser:
<Label Text="http://www.google.com/" />
I can't find anything in the Xamarin Forms API about this and the internet has vague and limited information on this topic in Xamarin.Forms.
Is this possible? If so, could someone please point me in the right direction? Thanks in advance to anyone who answers.
You can't really do this because Labels by default don't respond to user input, but you can achieve something similar with gestures
using Xamarin.Forms;
using Xamarin.Essentials;
Label label = new Label();
label.Text = "http://www.google.com/";
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += async (s, e) => {
// Depreciated - Device.OpenUri( new Uri((Label)s).Text);
await Launcher.OpenAsync(new Uri(((Label)s).Text));
};
label.GestureRecognizers.Add(tapGestureRecognizer);
I made this little class to handle it:
public class SimpleLinkLabel : Label
{
public SimpleLinkLabel(Uri uri, string labelText = null)
{
Text = labelText ?? uri.ToString();
TextColor = Color.Blue;
GestureRecognizers.Add(new TapGestureRecognizer { Command = new Command(() => Device.OpenUri(uri)) });
}
}
And a bit more involved if you want to underline it too:
public class LinkLabel : StackLayout
{
private SimpleLinkLabel label;
public LinkLabel(Uri uri, string labelText = null, bool underlined = true)
{
// Remove bottom padding
Padding = new Thickness(Padding.Left, Padding.Top, Padding.Right, 0);
VerticalOptions = LayoutOptions.Center;
Children.Add(label = new SimpleLinkLabel(uri, labelText));
if (underlined)
Children.Add(new BoxView { BackgroundColor = Color.Blue, HeightRequest = 1, Margin = new Thickness(0, -8, 0, 0) });
}
public TextAlignment HorizontalTextAlignment { get { return label.HorizontalTextAlignment; } set { label.HorizontalTextAlignment = value; } }
}
The latter class inspired by this post: how to underline in xamarin forms
Edit: XLabs have a HyperLinkLabel too.
<Label LineBreakMode="WordWrap">
<Label.FormattedText>
<FormattedString>
<Span Text="Google">
<Span.GestureRecognizers>
<TapGestureRecognizer Tapped="Handle_Tapped" />
</Span.GestureRecognizers>
</Span>
</FormattedString>
</Label.FormattedText>
</Label>
public async void Handle_Tapped(object sender, EventArgs e)
{
await Browser.OpenAsync(new Uri(url), BrowserLaunchMode.SystemPreferred);
}
use a button and a xamarin.forms.theme nuget
<Button StyleClass = "Link"/>
https://developer.xamarin.com/guides/xamarin-forms/user-interface/themes/light/
If you want to do this with MVVM, you can create a Label with a blue text colour and a GestureRecognizers to hook it up to a Command:
<Label TextColor="Blue" Text="{Binding Model.LinkDescription}">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ClickCommand}" CommandParameter="{Binding Model.LinkURL}"/>
</Label.GestureRecognizers>
</Label>
In your ViewModel you can launch the default Browser using the Xamarin Essentials Nuget Package:
private Boolean IsValidUri(String uri)
{
try
{
new Uri(uri);
return true;
}
catch
{
return false;
}
}
public ICommand ClickCommand => new Command<string>(async (url) =>
{
try
{
if (!string.IsNullOrEmpty(url))
{
if (!url.Trim().StartsWith("http", StringComparison.OrdinalIgnoreCase))
{
url = "http://" + url;
}
if (IsValidUri(url))
{
await Browser.OpenAsync(new Uri(url), BrowserLaunchMode.SystemPreferred);
}
}
}
catch(Exception ex)
{
Debug.WriteLine(ex.Message);
}
});
I have this longListSelector:
<phone:LongListSelector
x:Name="ListaMensajesTablon"
ItemsSource="{Binding Mensajes}"
ItemTemplate="{StaticResource MensajesTablonDataTemplate}"
SelectionChanged="MensajeTablonSelected"/>
With this ItemTemplate:
<DataTemplate x:Key="MensajesTablonDataTemplate">
<Grid>
<Button MaxHeight="85" MaxWidth="95" MinHeight="85" MinWidth="95" Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Center" Click="Button_Click" BorderBrush="Transparent">
<Button.Content>
<Image x:Name="imagenFav" MaxHeight="75" MaxWidth="75" MinHeight="75" MinWidth="75"
Source="{Binding userFav, Converter={StaticResource BoolToHeart}}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Button.Content>
</Button>
</Grid>
</DataTemplate>
This code-behind:
private void Button_Click(object sender, RoutedEventArgs e)
{
botonFavPulsado = true;
botonAmor = (Button)sender;
}
private void MensajeTablonSelected(object sender, SelectionChangedEventArgs e)
{
if(botonFavPulsado)
{
var myItem = ((LongListSelector)sender).SelectedItem as MensajeTablon;
if(botonAmor!=null)
{
if (myItem.userFav)
{
botonAmor.Content = new Image
{
Source = new BitmapImage(new Uri("icons/heart.red.png", UriKind.Relative))
};
}
else
{
botonAmor.Content = new Image
{
Source = new BitmapImage(new Uri("icons/heart.white.png", UriKind.Relative))
};
}
}
botonFavPulsado = false;
}
}
I want to do is that when you press a button that is inside an element of LongListSelector change the picture . The first time I press the button enters in the function Button_Click and then enters in the function MensajeTablonSelected function and change the image (good). The problem is the second time I press the same button is entering in the function Button_Click function and does not enter in the function MensajeTablonSelected
Resume : ToggleButton in LongItemSelector working the first time but not the second one
Problem solved:
private void MensajeTablonSelected(object sender, SelectionChangedEventArgs e)
{
if (((LongListSelector)sender).SelectedItem != null)
if(botonFavPulsado)
{
var myItem = ((LongListSelector)sender).SelectedItem as MensajeTablon;
if(botonAmor!=null)
{
if (myItem.userFav)
{
botonAmor.Content = new Image
{
Source = new BitmapImage(new Uri("icons/heart.red.png", UriKind.Relative))
};
}
else
{
botonAmor.Content = new Image
{
Source = new BitmapImage(new Uri("icons/heart.white.png", UriKind.Relative))
};
}
}
botonFavPulsado = false;
//Unselect ITEM
((LongListSelector)sender).SelectedItem = null;
}
}
This solution have a problem, the function MensajeTablonSelected is called again.