Skip to content

Instantly share code, notes, and snippets.

@yinyue200
Last active February 24, 2021 13:12
Show Gist options
  • Save yinyue200/98c576712155b8fcec629c11d994a8bb to your computer and use it in GitHub Desktop.
Save yinyue200/98c576712155b8fcec629c11d994a8bb to your computer and use it in GitHub Desktop.
ContentDialog for Xamarin 3.0
//*********************************************************
//
// Copyright (c) yinyue200.com. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
#if ANDROID
using Android.Support.V7.App;
#elif __IOS__
using Moespirit.Xamarin.iOSControls;
#endif
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Foundation;
using Xamarin.Forms;
namespace Windows.UI.Xaml.Controls
{
public class ContentDialog : BindableObject
{
public View Content
{
get { return (View)GetValue(ContentProperty); }
set { SetValue(ContentProperty, value); }
}
// Using a DependencyProperty as the backing store for Content. This enables animation, styling, binding, etc...
public static readonly BindableProperty ContentProperty =
BindableProperty.Create(nameof(Content), typeof(View), typeof(ContentDialog), propertyChanged: (BindableObject obj, object old, object newobj)=>
{
var cd = (ContentDialog)obj;
var cp = new ContentPage() { Content = (View)newobj };
cd.NativeView = yfxsApp.Controls.Common.Page2View.ConvertToNativeView(cp);
});
#if ANDROID
Android.Views.View NativeView;
AlertDialog dialog;
#elif __IOS__
UIKit.UIView NativeView;
CustomIOSAlertView dialog;
#endif
public string CloseButtonText
{
get { return (string)GetValue(CloseButtonTextProperty); }
set { SetValue(CloseButtonTextProperty, value); }
}
// Using a DependencyProperty as the backing store for CloseButtonText. This enables animation, styling, binding, etc...
public static readonly BindableProperty CloseButtonTextProperty =
BindableProperty.Create(nameof(CloseButtonText), typeof(string), typeof(ContentDialog));
//public ContentDialogButton DefaultButton
//{
// get { return (ContentDialogButton)GetValue(DefaultButtonProperty); }
// set { SetValue(DefaultButtonProperty, value); }
//}
//// Using a DependencyProperty as the backing store for DefaultButton. This enables animation, styling, binding, etc...
//public static readonly BindableProperty DefaultButtonProperty =
// BindableProperty.Create(nameof(DefaultButton), typeof(ContentDialogButton), typeof(ContentDialog));
//public bool FullSizeDesired
//{
// get { return (bool)GetValue(FullSizeDesiredProperty); }
// set { SetValue(FullSizeDesiredProperty, value); }
//}
//// Using a DependencyProperty as the backing store for FullSizeDesired. This enables animation, styling, binding, etc...
//public static readonly BindableProperty FullSizeDesiredProperty =
// BindableProperty.Create(nameof(FullSizeDesired), typeof(bool), typeof(ContentDialog));
//public bool IsPrimaryButtonEnabled
//{
// get { return (bool)GetValue(IsPrimaryButtonEnabledProperty); }
// set { SetValue(IsPrimaryButtonEnabledProperty, value); }
//}
//// Using a DependencyProperty as the backing store for IsPrimaryButtonEnabled. This enables animation, styling, binding, etc...
//public static readonly BindableProperty IsPrimaryButtonEnabledProperty =
// BindableProperty.Create(nameof(IsPrimaryButtonEnabled), typeof(bool), typeof(ContentDialog));
//public bool IsSecondaryButtonEnabled
//{
// get { return (bool)GetValue(IsSecondaryButtonEnabledProperty); }
// set { SetValue(IsSecondaryButtonEnabledProperty, value); }
//}
//// Using a DependencyProperty as the backing store for IsSecondaryButtonEnabled. This enables animation, styling, binding, etc...
//public static readonly BindableProperty IsSecondaryButtonEnabledProperty =
// BindableProperty.Create("IsSecondaryButtonEnabled", typeof(bool), typeof(ContentDialog));
public string PrimaryButtonText
{
get { return (string)GetValue(PrimaryButtonTextProperty); }
set { SetValue(PrimaryButtonTextProperty, value); }
}
// Using a DependencyProperty as the backing store for PrimaryButtonText. This enables animation, styling, binding, etc...
public static readonly BindableProperty PrimaryButtonTextProperty =
BindableProperty.Create(nameof(PrimaryButtonText), typeof(string), typeof(ContentDialog));
public string SecondaryButtonText
{
get { return (string)GetValue(SecondaryButtonTextProperty); }
set { SetValue(SecondaryButtonTextProperty, value); }
}
// Using a DependencyProperty as the backing store for SecondaryButtonText. This enables animation, styling, binding, etc...
public static readonly BindableProperty SecondaryButtonTextProperty =
BindableProperty.Create(nameof(SecondaryButtonText), typeof(string), typeof(ContentDialog));
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
// Using a DependencyProperty as the backing store for Title. This enables animation, styling, binding, etc...
public static readonly BindableProperty TitleProperty =
BindableProperty.Create(nameof(Title), typeof(string), typeof(ContentDialog));
public async void Hide()
{
var args = new ContentDialogClosingEventArgs() { Result = result };
Closing?.Invoke(this,args);
await args.od.WaitOneAsync();
if (args.Cancel)
return;
#if ANDROID
if(dialog.IsShowing)
dialog.Cancel();
#elif __IOS__
dialog.Close();
dialog.Dispose();
dialog = null;
#endif
Closed?.Invoke(this, new ContentDialogClosedEventArgs() { Result = result });
}
Content​Dialog​Result result;
public async Task<Content​Dialog​Result> ShowAsync()
{
var od = new Yinyue200.OperationDeferral.OperationDeferral();
od.Start();
#if ANDROID
AlertDialog.Builder builder = new AlertDialog.Builder(Forms.Context);
builder.SetView(NativeView);
if(Title!=null)
{
builder.SetTitle(Title);
}
if (PrimaryButtonText!=null)
{
builder.SetPositiveButton(PrimaryButtonText, (sen,args)=>
{
primaryclick();
});
}
if(SecondaryButtonText !=null)
{
builder.SetNegativeButton(SecondaryButtonText, (sen, args) =>
{
secondaryclick();
});
}
if(CloseButtonText!=null)
{
builder.SetNeutralButton(CloseButtonText, (sen, args) =>
{
closeclick();
});
}
dialog = builder.Show();
#else
dialog = new CustomIOSAlertView();
dialog.ContainerView = NativeView;
yfxsApp.DeveloperDebug.NeedAttention();
//TODO:Settitle
string[] ttles = new string[3];
ttles[0] = PrimaryButtonText;
ttles[1] = SecondaryButtonText;
ttles[2] = CloseButtonText;
var buttons = new List<string>(3);
foreach (var one in ttles)
{
if (one != null)
buttons.Add(one);
}
dialog.CloseOnTouchUpOutside = true;
dialog.ButtonTitles = buttons.ToArray();
dialog.ButtonClicked += (sender, e) =>
{
int newid = e.ButtonId;
switch(e.ButtonId)
{
case 0:
if(PrimaryButtonText!=null)
{
primaryclick();
}
else if (SecondaryButtonText != null)
{
secondaryclick();
}
else
{
closeclick();
}
break;
case 1:
if (PrimaryButtonText != null && SecondaryButtonText != null)
{
secondaryclick();
}
else if(PrimaryButtonText!=null|| SecondaryButtonText != null)
{
closeclick();
}
break;
case 2:
closeclick();
break;
}
};
dialog.Show();
#endif
Closed += (s, e) =>
{
od.Complete();
};
await od.WaitOneAsync();
return result;
}
private void closeclick()
{
result = ContentDialogResult.None;
NewMethod(CloseButtonClick);
}
private void secondaryclick()
{
result = ContentDialogResult.Secondary;
NewMethod(SecondaryButtonClick);
}
private void primaryclick()
{
result = ContentDialogResult.Primary;
NewMethod(PrimaryButtonClick);
}
private async void NewMethod(TypedEventHandler<ContentDialog, ContentDialogButtonClickEventArgs> clevent)
{
try
{
var aargs = new ContentDialogButtonClickEventArgs();
clevent?.Invoke(this, aargs);
await aargs.od.WaitOneAsync();
if (!aargs.Cancel)
{
Hide();
}
}
catch
{
throw;
}
}
/// <summary>
/// 关闭对话框后发生。
/// </summary>
public event TypedEventHandler<ContentDialog, ContentDialogClosedEventArgs> Closed;
/// <summary>
/// 发生对话框开始关闭之后,但它关闭之前,并在 Windows.UI.Xaml。发生 Controls.ContentDialog.Closed 事件。
/// </summary>
public event TypedEventHandler<ContentDialog, ContentDialogClosingEventArgs> Closing;
/// <summary>
/// 对话框打开后发生。
/// </summary>
public event TypedEventHandler<ContentDialog, ContentDialogOpenedEventArgs> Opened;
/// <summary>
/// 点击主按钮后发生。
/// </summary>
public event TypedEventHandler<ContentDialog, ContentDialogButtonClickEventArgs> PrimaryButtonClick;
/// <summary>
/// 点击次按钮后发生。
/// </summary>
public event TypedEventHandler<ContentDialog, ContentDialogButtonClickEventArgs> SecondaryButtonClick;
/// <summary>
/// 已点击关闭按钮后发生。
/// </summary>
public event TypedEventHandler<ContentDialog, ContentDialogButtonClickEventArgs> CloseButtonClick;
}
//public enum ContentDialogButton
//{
// /// <summary>
// /// The close button is the default.
// /// </summary>
// Close,
// /// <summary>
// /// No button is specified as the defaul
// /// </summary>
// None,
// /// <summary>
// /// The primary button is the default.
// /// </summary>
// Primary,
// /// <summary>
// /// The secondary button is the default.
// /// </summary>
// Secondary,
//}
public enum Content​Dialog​Result
{
/// <summary>
/// No button was tapped.
/// </summary>
None,
/// <summary>
/// The primary button was tapped by the user.
/// </summary>
Primary,
/// <summary>
/// The secondary button was tapped by the user.
/// </summary>
Secondary,
}
public sealed class ContentDialogClosedEventArgs : EventArgs
{
//
// 摘要:
// 获取 Windows.UI.Xaml。按钮的 Controls.ContentDialogResult 单击事件。
//
// 返回结果:
// 按钮单击事件的结果。
public ContentDialogResult Result { get; internal set; }
}
//
// 摘要:
// 为关闭事件提供数据。
public sealed class ContentDialogClosingEventArgs : EventArgs
{
//
// 摘要:
// 获取 Windows.UI.Xaml。应用可以使用异步响应结束事件的 Controls.ContentDialogClosingDeferral。
//
// 返回结果:
// Windows.UI.Xaml。应用可以使用异步响应结束事件的 Controls.ContentDialogClosingDeferral。
public Yinyue200.OperationDeferral.OperationDeferral GetDeferral()
{
od.Start();
return od;
}
internal Yinyue200.OperationDeferral.OperationDeferral od = new Yinyue200.OperationDeferral.OperationDeferral();
//
// 摘要:
// 获取或设置一个可取消正在关闭的对话框的值。 一个 * * true * * Windows.UI.Xaml 值。Controls.ContentDialogButtonClickEventArgs.Cancel
// 取消默认行为。
//
// 返回结果:
// 取消关闭对话框为 true;否则为 false。
public bool Cancel { get; set; }
//
// 摘要:
// 获取 Windows.UI.Xaml。结束事件的 Controls.ContentDialogResult。
//
// 返回结果:
// Windows.UI.Xaml。结束事件的 Controls.ContentDialogResult。
public ContentDialogResult Result { get; internal set; }
}
public sealed class ContentDialogOpenedEventArgs : EventArgs
{
}
public sealed class ContentDialogButtonClickEventArgs : EventArgs
{
//
// 摘要:
// 获取 Windows.UI.Xaml。应用可以使用异步响应一个按钮的 Controls.ContentDialogButtonClickDeferral
// 单击事件。
//
// 返回结果:
// Windows.UI.Xaml。应用可以使用异步响应一个按钮的 Controls.ContentDialogButtonClickDeferral 单击事件。
public Yinyue200.OperationDeferral.OperationDeferral GetDeferral()
{
od.Start();
return od;
}
internal Yinyue200.OperationDeferral.OperationDeferral od = new Yinyue200.OperationDeferral.OperationDeferral();
//
// 摘要:
// 获取或设置一个可取消按钮点击的值。 一个 * * true * * Windows.UI.Xaml 值。Controls.ContentDialogButtonClickEventArgs.Cancel
// 取消默认行为。
//
// 返回结果:
// 取消按钮单击为 true;否则为 false。
public bool Cancel { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment