Xamrin.Forms アラートダイアログ(DisplayAlert)のボタンの文字色の変更方法

Xamrin.Forms アラートダイアログ(DisplayAlert)のボタンの文字色の変え方を説明します。

1.共通プロジェクトに各OSのダイアログを呼び出すインターフェースを実装

public interface ICustomDisplayAlert {
    Task<bool> DisplayAlert(string title, string message, string accept, string cancel);
}

2.Androidプロジェクト内のResources>values>styles.xmlに文字色を定義する

<style name="CustomStyle" parent="Widget.AppCompat.Button.Borderless.Colored"/>
<style name="CustomStyle.Negative">
    <item name="android:textColor">#0000ff</item>
</style>
<style name="CustomStyle.Positive">
    <item name="android:textColor">#ff0000</item>
</style>
<style name="CustomDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="buttonBarNegativeButtonStyle">@style/CustomStyle.Negative</item>
    <item name="buttonBarPositiveButtonStyle">@style/CustomStyle.Positive</item>
</style>

3.Androidプロジェクト内 MainActivity.cs内にContextを外から参照できる変数を用意

public static Context context;
protected override void OnCreate(Bundle savedInstanceState) {
    ~
    ~
    context = this;
}

4.Androidプロジェクト内にダイアログを表示するクラスを追加

using Xamarin.Forms;
using System.Threading.Tasks;
using TestPrj;
using TestPrj.Droid;

[assembly: Dependency(typeof(CustomDisplayAlert))]
namespace TestPrj.Droid {
    public class CustomDisplayAlert : ICustomDisplayAlert {
        public CustomDisplayAlert() { }

        public Task<bool> DisplayAlert(string title, string message, string accept, string cancel) {
            var taskComplete = new TaskCompletionSource<bool>();
            var alert = new Android.Support.V7.App.AlertDialog.Builder(MainActivity.context, global::TestPrj.Droid.Resource.Style.CustomDialogStyle);
            alert.SetTitle(title);
            alert.SetMessage(message);
            alert.SetNegativeButton(cancel, (sender, e) => {
                taskComplete.SetResult(false);
            });
            alert.SetPositiveButton(accept, (sender, e) => {
                taskComplete.SetResult(true);
            });
            Device.BeginInvokeOnMainThread(() => alert.Create().Show());
            return taskComplete.Task;
        }
    }
}

5.iOSプロジェクト内にダイアログを表示するクラスを追加

using Xamarin.Forms;
using System.Threading.Tasks;
using UIKit;
using TestPrj;
using TestPrj.iOS;
using Foundation;

[assembly: Dependency(typeof(CustomDisplayAlert))]
namespace TestPrj.iOS {
    public class CustomDisplayAlert : ICustomDisplayAlert {
        public Task<bool> DisplayAlert(string title, string message, string accept, string cancel) {
            var taskComplete = new TaskCompletionSource<bool>();
            UIApplication.SharedApplication.InvokeOnMainThread(() => {
                var alertController = UIAlertController.Create(title, message, UIAlertControllerStyle.Alert);

                var acceptAction = UIAlertAction.Create(accept, UIAlertActionStyle.Default, x => {
                    taskComplete.SetResult(true);
                });
                acceptAction.SetValueForKey(UIColor.Green, new NSString("titleTextColor"));
                alertController.AddAction(acceptAction);

                var cancelAction = UIAlertAction.Create(cancel, UIAlertActionStyle.Cancel, x => {
                    taskComplete.SetResult(false);
                });
                cancelAction.SetValueForKey(UIColor.Orange, new NSString("titleTextColor"));
                alertController.AddAction(cancelAction);

                var controller = GetViewController();
                controller.PresentViewController(alertController, true, null);
            });
            return taskComplete.Task;
        }

        UIViewController GetViewController() {
            var rootViewController = UIApplication.SharedApplication.KeyWindow.RootViewController;

            if (rootViewController.PresentedViewController == null)
                return rootViewController;

            if (rootViewController.PresentedViewController is UINavigationController)
                return ((UINavigationController)rootViewController.PresentedViewController).VisibleViewController;

            if (rootViewController.PresentedViewController is UITabBarController)
                return ((UITabBarController)rootViewController.PresentedViewController).SelectedViewController;

            return rootViewController.PresentedViewController;
        }
    }
}

6.呼び出して使う

await DependencyService.Get<ICustomDisplayAlert>().DisplayAlert("title", "msg", "OK", "NO");
タイトルとURLをコピーしました