Currently, I have a slider which allows the user to submit their score into the Azure database, to do this the user has to move the slider to any number from their previous score. I want to change this now to allow the user to be able to submit the same score as their previous one now.
This is my code for my slider:
<local:ExtendedRangeSlider
RangeEnd="100"
Name="{Binding Usersymptomid}"
Value="{Binding Lastfeedbackscore}"
RangeStart="100"
ShowValueLabel="false"
ShowRange="false"
TrackSelectionThickness="3"
HeightRequest="40"
StepFrequency="1"
Grid.Row="4"
TickFrequency="10"
Grid.Column="0"
TickPlacement="BottomRight"
Grid.ColumnSpan="2"
Orientation="Horizontal"
Margin="0,0,0,8"
ValueChanging="Handle_ValueChanging"/>
And my submit button:
async void SubmitFeedback_Clicked(object sender, EventArgs e)
{
var response = await DisplayAlert("Confirm Symptom Intensity", "Are you sure you want to change symptom intensity to " + rangeSlider.Value.ToString() + "?", "Cancel", "OK");
if (response == false)
{
await AddSymptomFeedback(rangeSlider.IDValue, rangeSlider.Value.ToString());
}
else
{
await Navigation.PushAsync(new newviewsymptom());
return;
}
}
The code originally gave the user an error message asking them to change the value and didn't post to the database, I've tried commenting that part out but nothing happens unless I change the value of the slider.
Related
I am using Telerik's RadAutoComplete for having an autocomplete field. It is working fine with static data but on the basis of input received by user in autocomplete field, I have to execute the API and fetch data from there. List received in API response will be visible in autocomplete's suggestion view.
As soon as I am assigning my response to the ItemSource of RadAutoComplete, the text entered in the autocomplete is getting reset. For example: If I want to search "Friday", I entered "Fr" in autocomplete field. After receiving the response from the API that "Fr" will be removed from the autocomplete automatically and autocomplete text will be "".
XAML:
<telerikInput:RadAutoComplete
BorderColor="LightGray"
FilteredItemsChanged="autoCompleteUsers_FilteredItemsChanged"
ItemsSource="{Binding UserList}"
SearchThreshold="3"
ShowSuggestionView="True"
SuggestionItemSelected="autoCompleteUsers_SuggestionItemSelected"
TextSearchPath="Name">
<telerikInput:RadAutoComplete.SuggestionItemTemplate>
<DataTemplate>
<StackLayout HeightRequest="20">
<Label
Margin="2"
HorizontalOptions="Start"
Text="{Binding Item.Name}"
TextColor="Black"
VerticalOptions="Center" />
</StackLayout>
</DataTemplate>
</telerikInput:RadAutoComplete.SuggestionItemTemplate>
</telerikInput:RadAutoComplete>
Event
void autoCompleteUsers_FilteredItemsChanged(System.Object sender, Telerik.XamarinForms.Input.AutoComplete.FilteredItemsChangedEventArgs e)
{
var searchedText = (sender as RadAutoComplete).Text;
viewController.GetUserList(searchedText);
}
public async Task GetUserList(string searchedText)
{
// **reassigning userList with the response of API**
UserList = await _APIservice.GetUsers(searchedText);
}
Try using RadAutoCompleteView, it is recommended for Remote search.
https://docs.telerik.com/devtools/xamarin/controls/autocompleteview/autocompleteview-remote-search?_ga=2.230265054.335708323.1661762900-2099335098.1639588237
I am working on a Xamarin.forms project which has a ScrollView with a child of a StackLayout, whose child is a Label.
<ScrollView Grid.Row="0" Grid.Column="0"
x:Name="MessageScroll" BackgroundColor="Gainsboro">
<StackLayout BackgroundColor="Beige" Margin="2"
x:Name="MessageStack" Spacing="0">
<Label Text="Messages"/>
</StackLayout>
</ScrollView>
I want this to be a message window.
I will add onto this StackLayout new labels with messages.
I made a label with a new message(e.Message), added it onto Stacklayout, and then, scroll down the ScrollView show the last added label at the bottom of the ScollView.
Label newLabel = new Label();
newLabel.Text = e.Message;
MessageStack.Children.Add(newLabel);
await MessageScroll.ScrollToAsync(newLabel, ScrollToPosition.End, false);
the problem is ScrollToAsync doesn't ensure the last added label to be at the bottom when I added multiple message labels consecutively in a short period of time.
It seems because each call of ScrollToAsync is executed asynchronously so the last call for it wouldn't complete last.
How can I make this to work as what I want?
If you await the ScrollToAsync it will wait for scroll action to be completed. Anyway, here is a solution to scroll to bottom, you can give it a try.
async Task AddLabel(MessageEventArgs e)
{
Label newLabel = new Label();
newLabel.Text = e.Message;
MessageStack.Children.Add(newLabel);
await MessageScroll.ScrollToAsync(0, MessageStack.Height, false);
}
I have got a Map page which has got background Image, source of image is set to random image api
<Image x:Name="backgroundImage" Source="https://someImageApi" AbsoluteLayout.LayoutBounds="0,0,1,1" AbsoluteLayout.LayoutFlags="All" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Aspect="AspectFill"/>
I would like to refresh the image without any button click in Xamarin Forms. I have tried something below, but this is not working.
public Map()
{
InitializeComponent();
MessagingCenter.Send(this, "RefreshSchedulePage");
MessagingCenter.Subscribe<Map>(this, "RefreshSchedulePage", async (sender) =>
{
Navigation.InsertPageBefore(new Map(), this);
await Navigation.PopAsync();
});
}
You should Subscribe the notification before you Send it
InitializeComponent();
MessagingCenter.Subscribe<Map>(this, "RefreshSchedulePage", async (sender) =>
{
Navigation.InsertPageBefore(new Map(), this);
await Navigation.PopAsync();
});
And send the message in OnAppearing.
Why don't you use OnPropertyChanged? (And maybe Device.StartTimer? - In case you need a recurring pattern.) OnPropertyChanged should draw in all bindings again, meaning it should reach out to the api for the random image again.
InitializeComponent();
int interval = 1000;
Device.StartTimer(interval, () => {
backgroundImage.OnPropertyChanged("Source");
}
If you don't need an interval, simply use OnPropertyChanged on its own.
I have a really odd problem with variable scopes. A Listview named "TodoListView" is defined via xaml, and it's ItemSource populated from a SQListe database. Works. Inside the ListView I have a ViewCell to display the data row-wise.
<ContentPage ... x:Class="JanitorPro.MainPage" ...>
<StackLayout>
<ListView x:Name="TodoListView" Margin="20" ItemSelected="OnListItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand">
<Label Text="{Binding name}" VerticalTextAlignment="Center" HorizontalOptions="StartAndExpand" />
<Switch HorizontalOptions="End" IsToggled="{Binding done}" Toggled="DoneSwitchToggled"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
The codebehind looks like this (some irrelevant portions removed):
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
protected override async void OnAppearing()
{
base.OnAppearing();
// load Database
TodoListView.ItemsSource = await App.TodoDatabase.GetItemsAsync("SELECT * FROM [TodoItem]");
}
async void OnReloadButtonClicked(object sender, EventArgs e)
{
Debug.WriteLine("Reload Button Click");
TodoListView.ItemsSource = await App.TodoDatabase.GetItemsAsync("SELECT * FROM [TodoItem]");
Debug.WriteLine("Reload done.");
}
async void OnListItemSelected(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem != null)
{
await Navigation.PushAsync(new TodoItemPage
{
BindingContext = e.SelectedItem as TodoItem
});
}
}
private void DoneSwitchToggled(object sender, ToggledEventArgs e)
{
// TodoItem i = null;
TodoItem i = TodoListView.SelectedItem;
if (i != null)
{
Debug.WriteLine("Toggle: {0}", i.id);
}
}
}
}
The oddity has two stages. Before I inserted the DoneSwitchToggled event handler, every occurrance of TodoListView.ItemsSource got a red underline under TodoListView and a hint that "The name TodoListView does not exist in the current context". OK, I thought that VS was not smart enough to find a definition in the xaml file, because, despite of the warning, the program compiled and ran fine. TodoListView gets initialized and does correctly display the rows of the underlying database, so it does clearly exist at runtime.
Things went wild when I added the DoneSwitchToggled event handler to both XAML and the codebehind. All the sudden the program won't compile any longer but bail out with a CS0103 error "The name "TodoListView" does not exist in the current context". The error appears three times, with the line numbers pointing to the other occurrances of TodoListView in onAppearing() and OnReloadButtonClicked(). Huh? How the heck can the addition of a variable reference in an event handler render that variable invalid in completely different methods? OK, there was something fishy with the variable before (still don't know what ...), but it worked. Now it doesn't any more, whch doesn't make any sense for me. Furthermore, if I comment out the offending line in the DoneSwitchToggled event handler, and insert a dummy definition for i, like so:
TodoItem i = null;
// TodoItem i = TodoListView.SelectedItem;
everything is like before, VS still underlines the other appearances of TodoListView, but now the program builds and runs ok again.
Anyone who can explain this effect, and show me how correct my code? I think the objective is clear: DoneSwitchToggled is supposed to write back the switch value into the database (and do some other processing not shown in my stripped down sample), and though the "sender" object is correctly set to reference my button, I found no way to access the underlying data binding, since ToggledEventArgs unfortunately does seem to only pass the switch position "true" or "false", but - unlike the OnListItemSelected event handler - not pass any reference to the bound row through the second argument. So my idea was to use ListView.SelectedItem for this purpose.
Finally I figured it out myself. This seems to be a glitch in VS 2017. There is nothing wrong with TodoListView, so error CS0103 is misleading nonsense.
What VS really means is an error CS0266. TodoListView is defined by a generic list
List<TodoItem>
to access SelectedItem i need to typecast it:
TodoItem i = (TodoItem)TodoListView.SelectedItem;
This added, all errors are gone, app code builds OK.
Btw, unfortunately this approach to get at the item where the Switch has been flipped has proven not working, TodoListView does always return null for SelectedItem, seems that the ListView control doesn't see the button press. Need to find a different way to find the list item beneath the switch to get at the bound row id.
I've failed certification because I have an image that's all white. So when a user switches to the light theme it fails because you can't see it. How do I swap this imaged based on the theme applied?
Thank you in advance
Question Making an image control invert its colors depending on theme has a simple XAML only answer:
<Image HorizontalAlignment="Center"Stretch="None" Visibility="{StaticResource PhoneLightThemeVisibility}" Source="/MyApplication;component/imageDarkTheme.png" />
<Image HorizontalAlignment="Center" Stretch="None" Visibility="{StaticResource PhoneDarkThemeVisibility}"Source="/MyApplication;component/imageLightTheme.png" />
In XAML
<Image Source="{Binding ImageSource}" />
In the view model that contains property ImageSource
public string ImageSource
{
get
{
if( (Visibility)App.Current.Resources["PhoneDarkThemeVisibility"]
== Visibility.Visible ) {
return "/path/to/dark/image.png";
} else {
return "/path/to/light/image.png";
}
}
private set {}
}
This may not change the picture if the user tombstones your app, changes the theme and switches back to the app.
One way to handle that scenario is to cache the current theme setting in the App class constructor, then compare it with the current setting within App.Application_Activated, if they're different you'll need to somehow indicate that the above view model needs to fire a property changed notification for ImageSource.
For anyone following my comments above - I had to switch from ImageBrush to Image directly (xaml below)
<Button Tag="{Binding}" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="-10,20,0,0" BorderThickness="0" Width="105" Height="102" Click="ShowKioskOnMap_Click">
<Image Source="../images/arrow.png" Width="55" Height="53" ImageOpened="Image_ImageOpened"/>
</Button>
Next in the consructor of the page I'm using --I did the theme lookup to prevent any issues when the app state is restored from taking a phone call for instance (or just loading up the view for the first time)
InitializeComponent();
theme = ""; //field level var (could make it dark by default if needed)
if ((Visibility)App.Current.Resources["PhoneDarkThemeVisibility"] == Visibility.Visible)
{
theme = "dark";
}
else
{
theme = "light";
}
And I had to implement the following in my open event to switch based on theme
private void Image_ImageOpened(object sender, RoutedEventArgs e)
{
var brush = (sender as Image);
if (brush.Stretch == Stretch.Uniform)
{
if (theme == "light")
brush.Source = new BitmapImage(new Uri("../images/arrowLight.png", UriKind.Relative));
brush.Stretch = Stretch.Fill;
}
}