我正在閱讀 Xamarin 的源代碼,并遇到了這兩個對話框:TimePickerDialog
和DatePickerDialog
.
閱讀這些內容時,我看到有一個正在實體化的物件,我在其他任何地方都找不到。
我想知道這些偵聽器實作者的目的是什么,以及如何實際創建自己的(或者我什至需要自己創建)。我的目標是創建一些 custom PickerDialog
,所以我正在檢查它們是如何實作的。
這是TimePickerDialog
:
using System;
using System.Collections.Generic;
using Android.Runtime;
namespace Android.App {
public partial class TimePickerDialog {
public TimePickerDialog (Android.Content.Context context, EventHandler<TimeSetEventArgs> callBack, int hourOfDay, int minute, bool is24HourView)
// ** The IOnTimeSetListenerImplementor here **
: this (context, new IOnTimeSetListenerImplementor () { Handler = callBack }, hourOfDay, minute, is24HourView) {}
public TimePickerDialog (Android.Content.Context context, int theme, EventHandler<TimeSetEventArgs> callBack, int hourOfDay, int minute, bool is24HourView)
: this (context, theme, new IOnTimeSetListenerImplementor () { Handler = callBack }, hourOfDay, minute, is24HourView) {}
}
}
這是DatePickerDialog
:
using System;
using System.Collections.Generic;
using Android.Runtime;
namespace Android.App {
public partial class DatePickerDialog {
public partial class DateSetEventArgs {
public DateTime Date {
get { return new DateTime (Year, Month 1, DayOfMonth); }
}
#if ANDROID_24
[Obsolete ("This parameter in DateTimePickerDialog constructor is removed in Android API, so it will vanish from this automatically generated type too.")]
public int MonthOfYear {
get { return Month; }
}
#else
public int Month {
get { return monthOfYear; }
}
#endif
}
public DatePickerDialog (Android.Content.Context context, EventHandler<DateSetEventArgs> callBack, int year, int monthOfYear, int dayOfMonth)
// ** The IOnDateSetListenerImplementor here **
: this (context, new IOnDateSetListenerImplementor () { Handler = callBack }, year, monthOfYear, dayOfMonth) {}
public DatePickerDialog (Android.Content.Context context, int theme, EventHandler<DateSetEventArgs> callBack, int year, int monthOfYear, int dayOfMonth)
: this (context, theme, new IOnDateSetListenerImplementor () { Handler = callBack }, year, monthOfYear, dayOfMonth) {}
public void UpdateDate (DateTime date)
{
UpdateDate (date.Year, date.Month - 1, date.Day);
}
}
}
額外問題:為什么將這兩個類定義為部分類?我在這個 repo 的其他任何地方都找不到其他部分。也許我沒有正確搜索,或者可能是為了將來的擴展?
謝謝您的幫助!
uj5u.com熱心網友回復:
當我搜索元資料時,我發現了以下內容Android.App.DatePickerDialog
(通過在 Visual Studio 中右鍵單擊類名并選擇轉到定義很容易做到):
#region Assembly Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065
// C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v11.0\Mono.Android.dll
#endregion
#nullable enable
using Android.Content;
using Android.Runtime;
using Android.Widget;
using Java.Interop;
using System;
using System.ComponentModel;
using System.Diagnostics;
namespace Android.App
{
[Register("android/app/DatePickerDialog", DoNotGenerateAcw = true)]
public class DatePickerDialog : AlertDialog, IDialogInterfaceOnClickListener, IJavaObject, IDisposable, IJavaPeerable, DatePicker.IOnDateChangedListener
{
[Register(".ctor", "(Landroid/content/Context;)V", "", ApiSince = 24)]
public DatePickerDialog(Context context);
[Register(".ctor", "(Landroid/content/Context;I)V", "", ApiSince = 24)]
public DatePickerDialog(Context context, int themeResId);
public DatePickerDialog(Context context, EventHandler<DateSetEventArgs> callBack, int year, int monthOfYear, int dayOfMonth);
[Register(".ctor", "(Landroid/content/Context;Landroid/app/DatePickerDialog$OnDateSetListener;III)V", "")]
public DatePickerDialog(Context context, IOnDateSetListener? listener, int year, int month, int dayOfMonth);
public DatePickerDialog(Context context, int theme, EventHandler<DateSetEventArgs> callBack, int year, int monthOfYear, int dayOfMonth);
[Register(".ctor", "(Landroid/content/Context;ILandroid/app/DatePickerDialog$OnDateSetListener;III)V", "")]
public DatePickerDialog(Context context, int themeResId, IOnDateSetListener? listener, int year, int monthOfYear, int dayOfMonth);
protected DatePickerDialog(IntPtr javaReference, JniHandleOwnership transfer);
public virtual DatePicker DatePicker { get; }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override JniPeerMembers JniPeerMembers { get; }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[EditorBrowsable(EditorBrowsableState.Never)]
protected override Type ThresholdType { get; }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[EditorBrowsable(EditorBrowsableState.Never)]
protected override IntPtr ThresholdClass { get; }
public event EventHandler<DateSetEventArgs> DateSet;
[Register("onClick", "(Landroid/content/DialogInterface;I)V", "GetOnClick_Landroid_content_DialogInterface_IHandler")]
public virtual void OnClick(IDialogInterface dialog, int which);
[Register("onDateChanged", "(Landroid/widget/DatePicker;III)V", "GetOnDateChanged_Landroid_widget_DatePicker_IIIHandler")]
public virtual void OnDateChanged(DatePicker view, int year, int month, int dayOfMonth);
[Register("setOnDateSetListener", "(Landroid/app/DatePickerDialog$OnDateSetListener;)V", "GetSetOnDateSetListener_Landroid_app_DatePickerDialog_OnDateSetListener_Handler", ApiSince = 24)]
public virtual void SetOnDateSetListener(IOnDateSetListener? listener);
public void UpdateDate(DateTime date);
[Register("updateDate", "(III)V", "GetUpdateDate_IIIHandler")]
public virtual void UpdateDate(int year, int month, int dayOfMonth);
[Register("android/app/DatePickerDialog$OnDateSetListener", "", "Android.App.DatePickerDialog/IOnDateSetListenerInvoker")]
public interface IOnDateSetListener : IJavaObject, IDisposable, IJavaPeerable
{
[Register("onDateSet", "(Landroid/widget/DatePicker;III)V", "GetOnDateSet_Landroid_widget_DatePicker_IIIHandler:Android.App.DatePickerDialog/IOnDateSetListenerInvoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")]
void OnDateSet(DatePicker? view, int year, int month, int dayOfMonth);
}
public class DateSetEventArgs : EventArgs
{
public DateSetEventArgs(int year, int month, int dayOfMonth);
public DateTime Date { get; }
[Obsolete("This parameter in DateTimePickerDialog constructor is removed in Android API, so it will vanish from this automatically generated type too.")]
public int MonthOfYear { get; }
public int Year { get; }
public int Month { get; }
public int DayOfMonth { get; }
}
}
}
我看到IOnDateSetListener
介面是在類中定義的。我還注意到課程不再被標記partial
。
然后我也能夠找到DatePickerDialog IOnDateSetListener.xml
:
<Type Name="DatePickerDialog IOnDateSetListener" FullName="Android.App.DatePickerDialog IOnDateSetListener">
<TypeSignature Language="C#" Value="public interface DatePickerDialog.IOnDateSetListener : Android.Runtime.IJavaObject, IDisposable, Java.Interop.IJavaPeerable" />
<TypeSignature Language="ILAsm" Value=".class nested public interface auto ansi abstract DatePickerDialog/IOnDateSetListener implements class Android.Runtime.IJavaObject, class Java.Interop.IJavaPeerable, class System.IDisposable" />
<TypeSignature Language="DocId" Value="T:Android.App.DatePickerDialog.IOnDateSetListener" />
<TypeSignature Language="F#" Value="type DatePickerDialog.IOnDateSetListener = interface
 interface IJavaObject
 interface IDisposable
 interface IJavaPeerable" />
...
<AttributeName Language="C#">[Android.Runtime.Register("android/app/DatePickerDialog$OnDateSetListener", "", "Android.App.DatePickerDialog/IOnDateSetListenerInvoker")]</AttributeName>
<AttributeName Language="F#">[<Android.Runtime.Register("android/app/DatePickerDialog$OnDateSetListener", "", "Android.App.DatePickerDialog/IOnDateSetListenerInvoker")>]</AttributeName>
...
<a href="https://developer.android.com/reference/android/app/DatePickerDialog$OnDateSetListener" title="Reference documentation">Android platform documentation</a>
...
和DatePickerDialog.xml
:
<Type Name="DatePickerDialog" FullName="Android.App.DatePickerDialog">
<TypeSignature Language="C#" Value="public class DatePickerDialog : Android.App.AlertDialog, Android.Content.IDialogInterfaceOnClickListener, Android.Widget.DatePicker.IOnDateChangedListener, IDisposable, Java.Interop.IJavaPeerable" />
<TypeSignature Language="ILAsm" Value=".class public auto ansi beforefieldinit DatePickerDialog extends Android.App.AlertDialog implements class Android.Content.IDialogInterfaceOnClickListener, class Android.Runtime.IJavaObject, class Android.Widget.DatePicker/IOnDateChangedListener, class Java.Interop.IJavaPeerable, class System.IDisposable" />
<TypeSignature Language="DocId" Value="T:Android.App.DatePickerDialog" />
<TypeSignature Language="F#" Value="type DatePickerDialog = class
 inherit AlertDialog
 interface IDialogInterfaceOnClickListener
 interface IJavaObject
 interface IDisposable
 interface IJavaPeerable
 interface DatePicker.IOnDateChangedListener" />
<AssemblyInfo>
<AssemblyName>Mono.Android</AssemblyName>
<AssemblyVersion>0.0.0.0</AssemblyVersion>
</AssemblyInfo>
<Base>
<BaseTypeName>Android.App.AlertDialog</BaseTypeName>
</Base>
<Interfaces>
<Interface>
<InterfaceName>Android.Content.IDialogInterfaceOnClickListener</InterfaceName>
</Interface>
<Interface>
<InterfaceName>Android.Runtime.IJavaObject</InterfaceName>
</Interface>
<Interface>
<InterfaceName>Android.Widget.DatePicker IOnDateChangedListener</InterfaceName>
</Interface>
...
上述兩個檔案都提到了它。我最好的猜測是有構建事件使用這些資訊來構建跨語言方法并將它們注入到部分類中。c# DatePickerDialog
(來自元資料)可能是編譯時事件合并DatePickerDialog
- 問題中提到的 - 與構建和打包 Xamarin 庫時 XML 檔案中包含的資訊的結果。
偵聽器介面似乎特定于 and 的行為,DatePicker
并且TimePicker
似乎并非在每種情況下都是必需的。
與其嘗試復制該行為,不如創建一個擴展AlertDialog
并呼叫該SetView
方法的自定義對話框,這可能就是所需要的。
編輯: Xamarin 社區工具包中
還包含一個Popup
類,可以很容易地制作自定義對話框,就像問題中參考的那樣。請參閱此處的檔案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/470497.html