I'm new to the xaramin. forms and Im designing a quiz game. I want to make the button to be disabled after the user clicks it to prevent the user from choosing it again. I tried to use Isenable but it's not working.
if I miss putting some code, please point it out.
XAML CODE
<StackLayout>
<StackLayout>
<Button x:Name="C11" Text="$1" WidthRequest="50" HeightRequest="100" Clicked="C11_Clicked" />
<Button x:Name="C12" Text="$1" WidthRequest="50" HeightRequest="100" Clicked="C12_Clicked"/>
</StackLayout>
</StackLayout>
C# code
private void C11_Clicked(object sender, EventArgs e)
{
C11.IsEnabled = false;
Navigation.PushModalAsync(new C11());
}
updated part
private void continue_Clicked(object sender, EventArgs e)
{
MainPage m = new MainPage();
m.C11btn.IsEnabled = false;
Preferences.Set("ButtonEnableFlag", false);
Navigation.PushModalAsync(new MainPage());
}
protected override void OnAppearing()
{
base.OnAppearing();
var enableValue = Preferences.Get("ButtonEnableFlag", true);
MainPage m = new MainPage();
m.C11btn.IsEnabled = enableValue;
}
may i ask how to permanently disabled the button?
If you want to make the button disabled permanently, you need to save a custom status flag in device. Next time entering to this view, the button will be disabled by this custom status flag programmatically.
For example, we can use Xamarin.Essentials: Preferences to sace the custom status flag and override OnAppearing method as follows:
public partial class PageThird : ContentPage
{
public PageThird()
{
InitializeComponent();
}
private void Button_Clicked(object sender, EventArgs e)
{
MyButton.IsEnabled = false;
Preferences.Set("ButtonEnableFlag", false);
}
protected override void OnAppearing()
{
base.OnAppearing();
var enableValue = Preferences.Get("ButtonEnableFlag", true);
MyButton.IsEnabled = enableValue;
}
}
Here is the Xaml code of this page:
<ContentPage.Content>
<StackLayout Padding="20">
<Label Text="Welcome to PagePersonal!"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
<Button x:Name="MyButton" Text="Disable" Clicked="Button_Clicked"/>
</StackLayout>
</ContentPage.Content>
Now the button will be disabled permanently.
If you want to disable the button in another page, you only need to set the custom status flag in another page. Later when you back to needed page, the button will be disabled.
The another page code:
public partial class PageSecond : ContentPage
{
public PageSecond()
{
InitializeComponent();
}
private async void Button_Clicked(object sender, EventArgs e)
{
await Navigation.PushModalAsync(new PageThird());
}
private void Disable_Clicked(object sender, EventArgs e)
{
Preferences.Set("ButtonEnableFlag", false);
}
private void Enable_Clicked(object sender, EventArgs e)
{
Preferences.Set("ButtonEnableFlag", true);
}
}
Then it will work, no code need to change in the needed page.
Related
In my WinUI3 C# application I have a frame with a content page. Given that I set IsNavigationStackEnabled to true on the frame, I'd expect the current page to be pushed to the navigation stack when I navigate (using MyFrame.Navigate(...)) so I could use MyFrame.GoBack() to navigate back to the previous page.
However, trying to invoke MyFrame.GoBack() after navigating from one page to another always results in an exception: System.Runtime.InteropServices.COMException: 'Error HRESULT E_FAIL has been returned from a call to a COM component.'. What's more, the CanGoBack-property is always false.
Am I missing something or is the navigation stack just not managed by the frame in WinUI3 and do I need to do this manually?
This a working sample code for Frame navigation. Note that there's no IsNavigationStackEnabled in the code. IsNavigationStackEnabled is true by default.
MainWindow.xaml
<Grid ColumnDefinitions="*,*">
<StackPanel
Grid.Column="0"
Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Button
x:Name="Page1Button"
Click="Page1Button_Click"
Content="Page1" />
<Button
x:Name="Page2Button"
Click="Page2Button_Click"
Content="Page2" />
<Button
x:Name="Page3Button"
Click="Page3Button_Click"
Content="Page3" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button
x:Name="BackButton"
Click="BackButton_Click"
Content="Back" />
<Button
x:Name="NextButton"
Click="NextButton_Click"
Content="Next" />
</StackPanel>
<Frame x:Name="NavigationFrame" />
</StackPanel>
<ListView Grid.Column="1" ItemsSource="{x:Bind NavigationLogs}" />
</Grid>
MainWindow.xaml.cs
using Microsoft.UI.Xaml;
using System;
using System.Collections.ObjectModel;
namespace Frames;
public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
NavigateTo(typeof(Page1));
}
private ObservableCollection<string> NavigationLogs { get; } = new();
private void BackButton_Click(object sender, RoutedEventArgs e)
{
NavigateBack();
}
private void NextButton_Click(object sender, RoutedEventArgs e)
{
NavigateForward();
}
private void Page1Button_Click(object sender, RoutedEventArgs e)
{
NavigateTo(typeof(Page1));
}
private void Page2Button_Click(object sender, RoutedEventArgs e)
{
NavigateTo(typeof(Page2));
}
private void Page3Button_Click(object sender, RoutedEventArgs e)
{
NavigateTo(typeof(Page3));
}
private void NavigateTo(Type pageType)
{
this.NavigationFrame.Navigate(pageType);
NavigationLogs.Add($"Navigated to {pageType}.");
}
private void NavigateBack()
{
if (this.NavigationFrame.CanGoBack is true)
{
this.NavigationFrame.GoBack();
NavigationLogs.Add("Navigated back.");
}
else
{
NavigationLogs.Add("Cannot to navigate back.");
}
}
private void NavigateForward()
{
if (this.NavigationFrame.CanGoForward is true)
{
this.NavigationFrame.GoForward();
NavigationLogs.Add("Navigated forward.");
}
else
{
NavigationLogs.Add("Cannot to navigate forward.");
}
}
}
I am a developer with Xamarin.
I'm developing with Xamarin.Forms.
I would like to open a picker when a page transition occurs.
I searched for existing information and found the following information about opening the picker by using Focus().
<ContentPage
Appearing="OnContentPageAppearing"
>
<Picker x:Name="TypePicker"
ItemsSource="{Binding ItemTypes}"
SelectedItem="{Binding SelectedItemType}" />
private void OnContentPageAppearing(object sender, EventArgs e)
{
TypePicker.Focus();
}
However, this is not enough to open the Picker.
Do we need the equivalent of a Click or Tap event?
If so, how do I write the code?
You could use Rg.Plugins.Popup plugin to create a popup page with picker.
I am not sure how do you use the navigation. I use a button click event to open the pop up page first. And then when i close the pop up page, navigate to the another page.
The code of navigating to the pop up page.
private async void Button_Clicked(object sender, EventArgs e)
{
await PopupNavigation.Instance.PushAsync(new Popup_picker());
}
Popup page:
Xaml:
<rg:PopupPage xmlns:rg="http://rotorgames.com" xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App3.Popup_picker">
<rg:PopupPage.Animation>
<rg:ScaleAnimation
DurationIn="400"
DurationOut="300"
EasingIn="SinOut"
EasingOut="SinIn"
HasBackgroundAnimation="True"
PositionIn="Center"
PositionOut="Center"
ScaleIn="1.2"
ScaleOut="0.8" />
</rg:PopupPage.Animation>
<StackLayout Margin="60"
BackgroundColor="White">
<Picker x:Name="TypePicker"
ItemsSource="{Binding ItemTypes}"
ItemDisplayBinding="{Binding Item}"
SelectedItem="{Binding SelectedItemType}" Unfocused="TypePicker_Unfocused"/>
</StackLayout>
</rg:PopupPage>
ViewModel for the Popup page:
public class PickerViewModel
{
public IList<PickerModel> ItemTypes { get; set; }
public PickerModel SelectedItemType { get; set; }
public PickerViewModel()
{
ItemTypes = new List<PickerModel>()
{
new PickerModel() { Item="A"},
new PickerModel() { Item="B"},
new PickerModel() { Item="C"},
};
SelectedItemType = ItemTypes[0];
}
}
public class PickerModel
{
public string Item { get; set; }
}
Code behind: Do the navigation when you close the popip page.
public partial class Popup_picker : PopupPage
{
public Popup_picker()
{
InitializeComponent();
this.BindingContext = new PickerViewModel();
}
protected override Task OnAppearingAnimationBeginAsync()
{
return Content.FadeTo(1);
}
protected override Task OnAppearingAnimationEndAsync()
{
return Content.FadeTo(1);
}
private async void TypePicker_Unfocused(object sender, FocusEventArgs e)
{
await PopupNavigation.Instance.PopAsync();
}
protected async override void OnDisappearing()
{
base.OnDisappearing();
await Navigation.PushAsync(new Page1());
}
}
For more details about the Rg.Plugins.Popup, please refer to the link below. https://github.com/rotorgames/Rg.Plugins.Popup
I have ContentPage named MainPage.xaml with MainPageViewModel set.
MainPage has following content view
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:myViews= ...>
//this view has a button with 'Handle_Click'
<myViews.View1 ... />
<BoxView x:Name="boxView" .../>
</ContentPage>
View1 has View1.xaml.cs and has Handle_Click event as bellow
void Handle_Click(System.Object sender, System.EventArgs e)
{
// How to access 'boxView' in this file so that I can animate.
// I can only access 'boxView' in respective MainPage.xaml.cs
// if I cannot access it over here , then how to let MainPage.xaml.cs know to animate
}
I am doing animation in code behind because I believe animation is part of UI and hence needs to be done in code behind and not in VM. Also I cannot access boxview in VM by name to animate.
Please correct me in my approach.
As #Jason mentioned, since boxView belongs to MainPage it's better to handle it animation in MainPage's code-behind, for that you need to expose a public event handler of View1, subscribe to it in MainPage code-behind, and invoke it from view1 code-behind:
MainPage.xaml
<myViews.View1 x:Name="view1" />
MainPage.xaml.cs
protected override void OnAppearing()
{
base.OnAppearing();
view1.Clicked += View1_Clicked;
}
protected override void OnDisappearing()
{
base.OnDisappearing();
view1.Clicked -= View1_Clicked;
}
void View1_Clicked(object sender, System.EventArgs e)
{
// animate boxview
}
View1.xaml.cs
public event EventHandler Clicked;
void Button_Clicked(object sender, EventArgs e)
{
...
//checking null before invoking
Clicked?.Invoke(sender, e);
}
How would I reference the Master Detail Page (MenuNavigation) by a clickable button inside of Homepage.xaml.cs and Homepage.xaml?
I want the side menu to appear whenever I click the "menu" button. (see below)
I have tried MasterDetail.isPresentedProperty inside the clicked button event handler in Homepage.xaml.cs and cannot figure it out.
Please help!
MenuNavigation.xaml:
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App2.MenuNavigation"
xmlns:local="clr-namespace:App2">
<!--this is the Menu Hamburger sidebar -->
<MasterDetailPage.Master>
<ContentPage Title="Menu" Padding="20" BackgroundColor="#4B1388" >
<StackLayout Orientation="Vertical">
<Label Text="Menu" TextColor="White" FontSize="Large" FontAttributes="Bold" HorizontalOptions="Center"/>
<Button Text="Home"
TextColor="White" BackgroundColor="#4B1388"
Clicked="Button_Clicked_Home"/> <!-- event handler points to MenuNavigation C# file when button is clicked-->
<Button Text="About"
TextColor="White" BackgroundColor="#4B1388"
Clicked="Button_Clicked_About"/>
<Button Text="Help"
TextColor="White" BackgroundColor="#4B1388"
Clicked="Button_Clicked_Help"/>
</StackLayout>
</ContentPage>
</MasterDetailPage.Master>
<!--links to the detail pages from the hamburger sidebar -->
<MasterDetailPage.Detail>
</MasterDetailPage.Detail>
MenuNavigation.xaml.cs:
namespace App2
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MenuNavigation : MasterDetailPage
{
public MenuNavigation()
{
InitializeComponent();
//this is for no nav bar at top
var Homepage = new Homepage();
NavigationPage.SetHasNavigationBar(Homepage, false);
Detail = new NavigationPage(Homepage);
IsPresented = false; //this will make the side menu disappear when you select a page
}
private void Button_Clicked_Home(object sender, EventArgs e)
{
var Homepage = new Homepage();
NavigationPage.SetHasNavigationBar(Homepage, false);
Detail = new NavigationPage(Homepage);
IsPresented = false; //this will make the side menu disappear when you select a page
}
private void Button_Clicked_About(object sender, EventArgs e)
{
Detail = new NavigationPage(new About());
IsPresented = false;
}
private void Button_Clicked_Help(object sender, EventArgs e)
{
Detail = new NavigationPage(new Help());
IsPresented = false;
}
}
}
Homepage.xaml:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App2.Homepage"
Title="Homepage">
<Button Text="Menu" Clicked="MasterDetailButton_Pressed"/>
</ContentPage>
Hompage.xaml.cs:
namespace App2
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Homepage : ContentPage
{
public Homepage()
{
InitializeComponent();
VideoListView.ItemsSource = Videos; //allows for binding
}
private void MasterDetailButton_Pressed(object sender, EventArgs e)
{
MasterDetailPage.IsPresentedProperty.Equals(true);
//open the master detail page when button is clicked.
//MasterDetailPage.IsPresentedProperty.Equals(true);
//MenuNavigation.IsPresentedProperty.Equals(true);
}
}
}
You should get a reference of your MasterDetailPage and change the IsPresented property of the reference. As the MasterDetailPage has to be the root of the app, something like this should work: (App.Current.MainPage as MasterDetailPage).IsPresented = true;.
Hope it helps! :)
I have a WebBrowser control and I want to show some url by parameter on this control. Until the webbrower loaded the page, I need to show some progressbar or animation.
Please help me, here's what I have:
public partial class brw : PhoneApplicationPage
{
public brw()
{
InitializeComponent();
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string parameterValue = NavigationContext.QueryString["parameter"];
System.Uri uri = new System.Uri(parameterValue);
webbrowser.Source = uri;
}
private void WebBrowser_Navigating_1(object sender, Microsoft.Phone.Controls.NavigatingEventArgs e)
{
progressbar.Visibility = Visibility.Visible;
}
private void WebBrowser_Navigated_1(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
progressbar.Visibility = Visibility.Collapsed;
}
private void PhoneApplicationPage_Loaded_1(object sender, System.Windows.RoutedEventArgs e)
{
}
}
Thank you
This can be achieved by using LoadCompleted property.
XAML:
<ProgressBar x:Name="progressbar" IsIndeterminate="True"/>
<phone:WebBrowser x:Name="webbrw" IsScriptEnabled="True" LoadCompleted="yesLoaded"/>
.cs:
private void yesLoaded(object sender, NavigationEventArgs e)
{
this.progressbar.Visibility = Visibility.Collapsed;
this.progressbar.IsIndeterminate = False;
}
Have a look at this sample.
Hope it helps!
try this:
webbrowser.Navigate(new Uri(parameterValue));
instead of
webbrowser.Source = uri;
set Progressbar's Property IsIndeterminate="True"
<ProgressBar Foreground="Orange" x:Name="progressbar" Visibility="Collapsed" IsIndeterminate="True" Height="4" HorizontalAlignment="Left" Margin="10,66,0,0" VerticalAlignment="Top" Width="460" />