I am trying to learn how to create mobile apps using MAUI and have seen many MVVM examples which I find incomplete. For this reason, I thought I should try to learn MAUI using CodeBehind first before moving onto MVVM. I have completey the MAUI section from the Microsoft Learn website, but it didn't cover displaying websocket data in XAML.
I have the following:
XAML:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CodeBehindTicker.MainPage">
<ScrollView>
<VerticalStackLayout>
<Label
Text="Ticker value"
x:Name="lblTicker" />
<Button
x:Name="btnGetTicker"
Text="Get Ticker"
Clicked="btnGetTicker_Clicked"/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
CodeBehind:
using Binance.Net.Clients;
using Binance.Net.Objects;
namespace CodeBehindTicker;
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void btnGetTicker_Clicked(object sender, EventArgs e)
{
var socketClient = new BinanceSocketClient(new BinanceSocketClientOptions { });
socketClient.SpotStreams.SubscribeToBookTickerUpdatesAsync("BTCUSDT", data => {
lblTicker.Text = data.Data.BestAskPrice.ToString();
Console.WriteLine(data.Data.BestAskPrice.ToString());
});
socketClient.UnsubscribeAllAsync();
}
}
When I click the button, the websocket data displays in realtime in the console output, but the label only displays the very first data returned and does not automatically update as the data in the console output updates instantly.
Any idea why? For now, I just want to stick to basic CodeBehind without using MVVM.
My guess is since you are using A WebSocket which probably has some async code the text is not changed on the main thread.
All you need to do is something like this:
MainThread.BeginInvokeOnMainThread(() =>
lblTicker.Text = data.Data.BestAskPrice.ToString());
Hope this helps
Related
How do I make the status bar transparent and show the content behind it on Android using .NET MAUI?
I've seen this post, is there a way to recreate this using C#?
Similar to Google Maps:
Try this , in MauiProgram.cs
.ConfigureLifecycleEvents(events =>
{
#if ANDROID
events.AddAndroid(android => android.OnCreate((activity, bundle) => MakeStatusBarTranslucent(activity)));
static void MakeStatusBarTranslucent(Android.App.Activity activity)
{
activity.Window.SetFlags(Android.Views.WindowManagerFlags.LayoutNoLimits, Android.Views.WindowManagerFlags.LayoutNoLimits);
activity.Window.ClearFlags(Android.Views.WindowManagerFlags.TranslucentStatus);
activity.Window.SetStatusBarColor(Android.Graphics.Color.Transparent);
}
#endif
});
Install version 1.3.0+ of CommunityToolkit.Maui, Gerald also has a video about it on YT:
And then in your ContentPage do something like:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:mct="clr-namespace:CommunityToolkit.Maui.Behaviors;assembly=CommunityToolkit.Maui"
x:Class="MauiToolkitStatusBarBehaviorSample.MainPage">
<Page.Behaviors>
<mct:StatusBarBehavior StatusBarColor="Transparent" StatusBarStyle="LightContent" />
</Page.Behaviors>
For other pages, you might want to set it up again since this behaviour is somewhat global and might effect other pages.
this is my first time to start coding in mobile app (Xamarin) using C# and I'm trying to create button when I click it, Message Appear with some Information's I wrote this code in .xaml file :
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App1.MainPage">
<ContentPage.Content>
<StackLayout>
<Button Text="click Me"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center"
Clicked="OnButtonClicked"/>
<Label x:Name ="lblMessage" FontSize="Large"></Label>
</StackLayout>
</ContentPage.Content>
</ContentPage>
and I wrote this in c# file :
namespace App1
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void OnButtonClicked(object sender, EventArgs e)
{
lblMessage.Text = "save";
}
}
}
The error i had it's in lblMessage variable in c# file it's :
The name 'lblMessage' does not exist in the current context
I do it from youtube channel and this is was exactly what he did, but it's worked with him and gives an error with me, any idea or help ?
1.Clean your project first
2.Rebuild it, change your XAML file properties (Build Action) from Embedded Resource to C# complier, Rebuild your project (will throw errors).
3.Switch back your XAML file properties to Embedded Resource, Rebuild.
Refer to this link: https://forums.xamarin.com/discussion/96447/the-name-initializecomponent-does-not-exist-in-the-current-context
I have a simple Stacklayout that shows Buttons.
I want to be able to let children remove itself from the stacklayout.
this project is just for testing purposes, so every button is linked to the same event-handler.
private void Button_Pressed_1(object sender, EventArgs e)
{
stack.Children.RemoveAt(stack.Children.Count - 1);
}
everything's fine until one button removes itself, then the following unsupported error appears:
Unhandled Exception:
System.NotSupportedException: Unable to activate instance of type
Xamarin.Forms.Platform.Android.AppCompat.ButtonRenderer from native
handle 0xbfb79bfc (key_handle 0x3e59524).
Has anyone an idea how to accomplish this? Since it's a nonSupportedException a simple try & catch didn't do the job
EDIT:
I got it working, i registered the eventhandler to the Pressed-Event. Appearently that was the problem, when using the Clicke-Event everything works just fine.
What 's version of Xamarin which you are using? I tried with Xamarin.Form 3.0.0.561731 and it worked well.
Please check my code as bellow:
Xaml page:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:RemoveItSelf"
x:Class="RemoveItSelf.MainPage">
<StackLayout x:Name="stack">
<!-- Place new controls here -->
<Label Text="Welcome to Xamarin.Forms!"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Label Text="Welcome to Xamarin.Forms!"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Button Text="Remove" Clicked="PressMeButton_Clicked"></Button>
</StackLayout>
</ContentPage>
Xaml.cs page:
namespace RemoveItSelf
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void PressMeButton_Clicked(object sender, EventArgs e)
{
//stack.Children.RemoveAt(0);
stack.Children.RemoveAt(stack.Children.Count - 1);
}
}
}
I am trying to embed a native android spinner in a xamarin forms content page. I have had some joy embedding a check-box from the developer documentation but I want to add a spinner. From the documentation, I should be able to data-bind normally to any native control. So I data-bound an ObservableCollection of strings to a native spinner like so:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
xmlns:android="clr-
namespace:Android.Widget;assembly=Mono.Android;targetPlatform=Android"
xmlns:androidForms="clr-namespace:Xamarin.Forms;
assembly=Xamarin.Forms.Platform.Android;targetPlatform=Android"
x:Class="CashFlowBuddie.Views.SelectPage"
Title="{Binding Title}">
<ContentView HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
<Label Text="Hi there from new app" FontSize="Large" FontAttributes="Bold" TextColor="Aquamarine"/>
<android:Spinner x:Arguments="{x:Static androidForms:Forms.Context}" ItemsSource="{Binding TextNames}" />
</ContentView>
</ContentPage>
This is my xaml page's viewmodel:
public class SelectPageViewModel : ViewModelBase
{
private ObservableCollection<string> _text;
public ObservableCollection<string> TextNames
{
get { return _text; }
set { SetProperty(ref _text, value); }
}
public SelectPageViewModel(INavigationService navigationService, IPageDialogService dialogService):base(navigationService,dialogService)
{
Title = "Select Option Page";
TextNames = new ObservableCollection<string>
{
"First",
"Second",
"Third"
};
}
}
From this you can tell that its a prism powered xamarin forms app. And I register my page for navigation properly:
public partial class App : PrismApplication
{
public App(IPlatformInitializer initializer = null) : base(initializer) { }
protected override void OnInitialized()
{
InitializeComponent();
NavigationService.NavigateAsync("NavigationPage/MainPage/SelectPage");
}
protected override void RegisterTypes()
{
Container.RegisterTypeForNavigation<MainPage>();
Container.RegisterTypeForNavigation<MainNavigation>("NavigationPage");
Container.RegisterTypeForNavigation<SelectPage>();
}
}
I made sure that I disabled XamlC from AssemblyInfo.cs since I cannot use XamlC when embedding native controls and views. My app crashes when I do the data-binding to the observablecollection of textnames. So I would like to know if someone has done this and had any joy? I looked at the spinner in the xamarin.android docs says a xml backed string array is created and is the source of data for the spinner. I did something similar using an observablecollection but if I run the app it just crashes. If I run the app without the data binding, it works and shows the app with the spinner but no data.
Can anyone shed any light on how to get this done? looked at docs and nothing so far though I am still digging?
Thanks
You may refer to Subclassing Native Views, seems like for control like Spinner is not suitable for instantiating in XAML. The ItemsSource property should be created in the subclass of native Spinner
To check the official demo, you may refer to Subclassed Native Views.
I am having trouble with Xamarin forms navigation, as in, it does not work at all.
My code :
appname.cs
using System;
using Xamarin.Forms;
namespace List
{
public class App : Application {
public App () {
MainPage = new NavigationPage (new HomePage ());
}
}
}
homepage.xaml.cs
using System;
using Xamarin.Forms;
using System.ComponentModel;
using System.Globalization;
namespace List
{
public partial class HomePage : ContentPage {
public HomePage () {
InitializeComponent ();
}
public void OnButtonClicked (object sender, EventArgs args) {
Navigation.PushAsync (new DetailsPage ());
}
}
}
My intention is obviously to open a main page, have a button on there that goes to a second page upon press.
However this happens instead whenever the button is clicked:
error message
Could not load type 'UIKit.UIView_UITextField' from assembly 'Xamarin.Forms.Platform.iOS'.
Can someone tell me what I'm doing wrong here?
Edit - code for DetailsPage, since this could be source of error:
using System;
using System.Collections.Generic;
using Xamarin.Forms;
namespace List
{
public partial class DetailsPage : ContentPage
{
public DetailsPage ()
{
InitializeComponent ();
}
}
}
Edit 2 - code for Xaml pages (thanks for the help everyone, I really appreciate it):
Homepage.xaml
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:List" x:Class="List.HomePage">
<ContentPage.Title>
1
</ContentPage.Title>
<Button Text="Click Me!" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" Clicked="OnButtonClicked" />
</ContentPage>
DetailsPage.Xaml:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="List.DetailsPage">
<Label Text="LOL"/>
</ContentPage>
In your xaml, the first element needs to be a layout (if you have multiple elements). I would try something similar to below and see if anything changes.
HomePage.xaml
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:List" x:Class="List.HomePage" Title="1">
<StackLayout>
<Button Text="Click Me!" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" Clicked="OnButtonClicked" />
</StackLayout>
</ContentPage>
DetailsPage.xaml
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="List.DetailsPage">
<StackLayout>
<Label Text="LOL"/>
</StackLayout>
</ContentPage>
Also, I noticed you were setting your title like using ContentPage.Title 1 ContentPage.Title. This is unnecessary. Just set the title directly in your ContentPage tag as I showed in the above example.
Well, I was having the same problem as you. I came across this solution of the xamarin guide.
It seems that in app.cs you need to call the using Xamarin.Forms.Xaml;
Right above your namespace insert [assembly:XamlCompilation(XamlCompilationOptions.Compile)]
But I really can't tell why. I'm Looking for the reason. Try to see if it resolves. In my case went well. Sorry about the bad english and the bad edit of the post, kind of new to this. But comparing all your code, it was missing this piece for you too, maybe this is the reason.
EDIT (12/01/2017) - Add
i found this, that might explain why was not working, seems like the function that we are using is part of a new set for Xamarin that helps him to became faster.
I can be wrong, if I am, please correct me someone that knows better.
Navigation.PushModalAsync(new DetailsPage());
Reference: http://developer.xamarin.com/guides/cross-platform/xamarin-forms/introduction-to-xamarin-forms/#Navigation