2
votes

How would I change the Button text color on a Xamarin Forms DisplayAlert dialog?

3

3 Answers

2
votes

Possible to change color with the help of custom renderers for each platform. You have access to native api inside custom renderer. But need to be sure that is needed, because it is not recommended (for iOS sure).

The UIAlertView class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified.

Relative topic for iOS here.

2
votes

FWIW, I opted to create a new ContentPage in XAML and show it with Navigation.PushModalAsync. In my case, it was the easiest way to simulate an alert and maintain control of all the styles.

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="YourNamespace.AlertPage"
             BackgroundColor="DarkGray"
             Padding="40">
    <ContentPage.Content>
        <StackLayout BackgroundColor="White" Padding="10">
            <Label x:Name="lblTitle" FontAttributes="Bold" FontSize="Large" Text="Title" HorizontalOptions="Center"></Label>
            <BoxView HeightRequest="1" BackgroundColor="DarkGray"></BoxView>
            <ScrollView Orientation="Vertical" VerticalOptions="FillAndExpand">
                <Label x:Name="lblText" FontSize="Medium"></Label>
            </ScrollView>
            <BoxView HeightRequest="1" BackgroundColor="DarkGray"></BoxView>
            <StackLayout Orientation="Horizontal">
                <Button x:Name="btn1" Text="Button 1" HorizontalOptions="CenterAndExpand"></Button>
                <Button x:Name="btn2" Text="Button 2" HorizontalOptions="CenterAndExpand"></Button>
            </StackLayout>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

C#:

public partial class AlertPage : ContentPage
{
    public Label LblTitle
    {
        get
        {
            return lblTitle;
        }
    }

    public Label LblText
    {
        get
        {
            return lblText;
        }
    }

    public Button Button1
    {
        get
        {
            return btn1;
        }
    }

    public Button Button2
    {
        get
        {
            return btn2;
        }
    }

    public AlertPage()
    {
        InitializeComponent();
    }
}

Implementation:

var ap = new AlertPage();
ap.LblTitle.Text = "Instructions";
ap.LblText.Text = "The text to display!";
ap.Button1.Text = "Done";
ap.Button1.Clicked += async (s, a) =>
{
    await Navigation.PopModalAsync();
};
ap.Button2.IsVisible = false;
await Navigation.PushModalAsync(ap);

Screenshot:

Screenshot from iPhone 7+

0
votes

i have created custom displayalert you can use task call back TaskCompletionSource as xamarin build DisplayAlert from it

    public async Task<bool> ShowDialogAsync(string title, string message, string acceptMessage, string cancelMessage)
                {
                    Grid ShowDialogMessage = null;
                    Grid CurrentPageGrid = (App.Instance.CurrentPage as ContentPage).Content as Grid;
                    TaskCompletionSource<bool> result = new TaskCompletionSource<bool>();
                    try
                    {
                        ShowDialogMessage = GenericView.CustomDisplayAlert(message, CurrentPageGrid.RowDefinitions.Count, CurrentPageGrid.ColumnDefinitions.Count, () =>
                        {
         //here you can add your implementation   
                            CurrentPageGrid.Children.Remove(ShowDialogMessage);

  result.SetResult(true);

                        },
                        () =>
                        {
         //here you can add your implementation      
                            CurrentPageGrid.Children.Remove(ShowDialogMessage);
                            result.SetResult(false);
                        }, title, acceptMessage, cancelMessage);

                        CurrentPageGrid.Children.Add(ShowDialogMessage);
                        return await result.Task;
                    }
                    catch (Exception ex)
                    {
                        return await App.Current.MainPage.DisplayAlert(title, message, acceptMessage, cancelMessage);
        #if DEBUG
                        throw ex;
        #endif
                    }

                }

in my method i added actions to implement the call back ,, method signature you can add your own design

 public static Grid CustomDisplayAlert(string message, int rows, int columns, Action acceptAction, Action cancelAction, string title = "", string acceptMessage = "", string cancelMessage = "")
        {           
             Grid overlay = new Grid
            {
                BackgroundColor = Color.FromRgba(0, 0, 0, 190),
                RowDefinitions = new RowDefinitionCollection { new RowDefinition { Height = GridLength.Star }, new RowDefinition { Height = GridLength.Auto }, new RowDefinition { Height = GridLength.Star } }
            };

                Grid.SetRowSpan(overlay, rows);

                Grid.SetColumnSpan(overlay, columns);


            Grid bodyView = new Grid();


            StackLayout stackMainView = new StackLayout
            {
                Margin = new Thickness(20)
            };
            StackLayout stackButtonsView = new StackLayout
            {
                Orientation=StackOrientation.Horizontal 
            };
            RoundedBox bgOverlay = new RoundedBox
            {
                CornerRadius = 4,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.FillAndExpand,
                BackgroundColor = Color.White
            };

            bodyView.Children.Add(bgOverlay);

            StackLayout elementsContainer = new StackLayout { Margin = new Thickness(10) };

            IconicLabel itemDescription = new IconicLabel { MoreReadable = true, Text = message, StyleId = "Myriad-Pro-L", HorizontalTextAlignment = TextAlignment.Center, HorizontalOptions = LayoutOptions.FillAndExpand, TextColor = (Color)(App.Current.Resources["OptioDark"]), FontSize = 18, Margin = new Thickness(15) };
            IconicLabel titleView = new IconicLabel { FontAttributes = FontAttributes.Bold, MoreReadable = true, Text = title, StyleId = "Myriad-Pro-L", HorizontalTextAlignment = TextAlignment.Center, HorizontalOptions = LayoutOptions.FillAndExpand, TextColor = (Color)(App.Current.Resources["OptioDark"]), FontSize = 22, Margin = new Thickness(15) };

            if (titleView.Text.Length != 0)
                elementsContainer.Children.Add(titleView);
            elementsContainer.Children.Add(itemDescription);


            bodyView.Children.Add(elementsContainer);

            IconicButton acceptBtn = new IconicButton
            {
                HeightRequest = 40,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.FillAndExpand,
                BackgroundColor = Color.White,
                Text = acceptMessage,
                TextColor = (Color)(App.Current.Resources["OptioDark"])
            };
            IconicButton cancelBtn = new IconicButton
            {
                HeightRequest = 40,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.FillAndExpand,
                BackgroundColor = Color.White,
                Text = cancelMessage,
                TextColor = (Color)(App.Current.Resources["OptioDark"])
            };
            acceptBtn.Clicked += (sender, e) =>
            {
                acceptAction?.Invoke();
            };
            cancelBtn.Clicked += (sender, e) =>
            {
                cancelAction?.Invoke();
            };

            stackButtonsView.Children.Add(acceptBtn);
            stackButtonsView.Children.Add(cancelBtn);

            stackMainView.Children.Add(bodyView);

            stackMainView.Children.Add(stackButtonsView);
            overlay.Children.Add(stackMainView, 0, 1);
            return overlay;

        }