1. 程式人生 > >Xamarin Forms開發框架之MvvmCross外掛精選

Xamarin Forms開發框架之MvvmCross外掛精選

在前兩篇老司機學Xamarin系列中,簡單介紹了Xamarin開發環境的搭建以及Prism和MvvmCross這兩個開發框架。不同的框架,往往不僅僅使用不同的架構風格,同時社群活躍度不同,各種功能模組和外掛數量也會有巨大差別。架構風格的好壞,屬於仁者見仁,但功能模組和外掛的好壞多寡,卻實實在在體現了社群的力量,是可以實打實拿出來練一練的。今天我們就來一起玩一玩MvvmCross提供的各種功能外掛,看看哪些輪子可以拿來直接就用的。

備註:本文主要關注相容Xamarin Forms xaml並且至少支援Droid和iOS平臺的外掛。

官方模組和外掛

在把視線放到社群貢獻的外掛之前,我們先來看看,MvvmCross框架官方提供了哪些模組、外掛:

Localization

Localization支援,對任何一個需要支援多國語言的App都必不可少。這個元件其實談不上MvvmCross特有,基本上是Xamarin官方文件推薦的最佳實踐。不過MvvmCross的VS專案模版直接包含了這個實現,並且整合到了MvvmCross自己的IoC容器的服務註冊。

在MvvmCross模版生成的專案中,資原始檔和獲取device當前語言的ILocalizeService介面定義在PCL Core專案中:

特定平臺的LocalizeService實現,定義在各自平臺專案的Services目錄中。在Setup類中預設將ILocalizeService註冊成為Singleton:

在任意xaml的View中,通過{res:Translate ResourceKey}這樣的格式繫結到控制元件的屬性:

DataBinding

資料繫結,是對任何App的View的顯示和互動必不可少的功能,這方面,Xamarin Forms本身的支援,就已經非常強悍了。MvvmCross有一個頁面專門介紹它對資料繫結的增強,然而,幾乎所有的增強貌似都是針對非Xamarin Forms xaml時期的Xamarin UI的資料繫結支援的,隨著Forms基於xaml的本身的資料繫結能力的出現和不斷增強,MvvmCross的這部分擴充套件其實已經過時了。

需要重點提及的是,在上面的LocalizeService元件的介紹中提到的{res:Translate ResourceKey}這樣的語法,其實是基於Xamarin Forms官方的

IMarkupExtension介面的擴充套件。而另一個可以用來擴充套件資料繫結的是IValueConverter介面。自定義的value converter,一般是用來在進行某個欄位的資料的儲存和資料的顯示之間的轉換的,但是,應該也可以利用它的語法來實現一些巧妙的資料繫結擴充套件。未來對Xamarin Forms UI元件的資料繫結的真正擴充套件,我想應該是基於上面提到的這兩個介面來實現。期望以後能看到各種有趣的外掛。當然,自己增加擴充套件也很容易。

簡單舉一個自定義IValueConverter的例子。假設我實現了下面這個自定義converter,用來自定義顯示某個model的長度屬性:

上面這個Converter的意思是,如果一個欄位在ViewModel裡面的屬性值為空,或者為0,顯示到頁面上時,顯示為Default,否則,顯示原來的值。假設ViewModel包含下面這個Length屬性,預設值為0:

xaml頁面的一個Label的Text,現在要繫結到上面這個Length屬性,並且,使用上面這個converter:

xaml裡稍微複雜一點,不過也不難理解。首先是定義一個名叫local的xmlns,然後需要將這個自定義的converter註冊到resource中,最後,在Label的Text屬性中指定繫結和converter。

Accelerometer

Accelerometer外掛讀取Accelerometer感測器的值。因為肯定要訪問裝置特定的API,它自然包含介面和對應不同裝置的具體實現。在專案中啟用一個MvvmCross的plugin,只需引用對應的nuget package。這個外掛對應的package是MvvmCross.Plugin.Accelerometer,可以從nuget.org下載。如果為一個包含shared PCL專案和Droid,iOS專案的solution新增這個外掛的nuget package後,會看到,shared專案只自動引用了包含IMvxAccelerometer介面的dll,而Droid專案和iOS專案則還自動引用了實現了IMvxAccelerometer介面的平臺特定的dll,並且,在Droid和iOS專案中的Boostrap目錄,會自動新增一個AccelerometerPluginBootstrap類,這個類是用於在App啟動時自動註冊外掛的,在這裡,特定來說,Bootstrap內部會自動註冊IMvxAccelerometer介面的實現。然後,我們就可以在程式碼裡訪問感測器的資料了。比如:

當訪問裝置特定的api時,還需要留意是否需要申請特定的裝置許可權。比如安卓裝置訪問Accelerometer就需要在Droid專案\Properties\AndroidManifest.xml檔案中新增一個users-feature如下:

可以看到,MvvmCross外掛的註冊機制非常巧妙,我一開始以為可能每個外掛至少需要有shared,droid,ios這樣多個nuget package,實際上,它只有一個nuget package,不同的專案型別自動引用了同一個package裡的不同target的dll,而且還自動添加了Bootstrap類,在框架層面通過反射和命名約定自動載入了外掛,使得整個外掛啟用過程不需手寫任何程式碼,非常贊!另外,除了通過Mvx.Resolve()獲取一個介面的例項之外,MvvmCross也支援建構函式注入,比如,可以為ViewModel的建構函式,新增一個IMvxAccelerometer引數,當ViewModel被IoC容器初始化時,建構函式的引數都會被自動注入。

Email

Email外掛,自然是用來發Email了。安裝nuget package:MvvmCross.Plugins.Email。它就包含了下面這個介面:

public interface IMvxComposeEmailTask
{
    void ComposeEmail(string to, string cc, string subject, string body, bool isHtml);
}

所以,發郵件至需要下面這樣的程式碼,不能再簡單了:

Mvx.Resolve<IMvxComposeEmailTask>()
   .ComposeEmail("[email protected]", 
                 string.Empty, 
                 "MvvmCross Email",
                 "I <3 MvvmCross",
                 false);

File

File外掛,提供了讀寫裝置本地檔案的能力。nuget package:MvvmCross.Plugins.File。Droid和iOS讀寫檔案時預設的當前目錄有差異(更多其他平臺的當前目錄,請參見官方文件):

  • Android - Context.FilesDir
  • iOS - Environment.SpecialFolder.MyDocuments

實現的介面如下:

public interface IMvxFileStore
{
    bool TryReadTextFile(string path, out string contents);
    bool TryReadBinaryFile(string path, out Byte[] contents);
    bool TryReadBinaryFile(string path, Func<Stream, bool> readMethod);
    void WriteFile(string path, string contents);
    void WriteFile(string path, IEnumerable<Byte> contents);
    void WriteFile(string path, Action<Stream> writeMethod);
    bool TryMove(string from, string to, bool deleteExistingTo);
    bool Exists(string path);
    bool FolderExists(string folderPath);
    string PathCombine(string items0, string items1);
    string NativePath(string path);
    void EnsureFolderExists(string folderPath);
    IEnumerable<string> GetFilesIn(string folderPath);
    void DeleteFile(string path);
    void DeleteFolder(string folderPath, bool recursive);
}

具體使用方法類似其他外掛,只需要通過Mvx.Resolve()方法拿到instance,呼叫相應方法即可,這裡就不詳述了。

Location

Location外掛,用來獲取使用者當前的GPS位置資訊。nuget package: MvvmCross.Plugins.Location。實現了IMvxLocationWatcher介面:

public interface IMvxLocationWatcher
{
    void Start(
        MvxLocationOptions options, 
        Action<MvxGeoLocation> success, 
        Action<MvxLocationError> error);
    void Stop();
    bool Started { get; }

    MvxGeoLocation CurrentLocation { get; }
    MvxGeoLocation LastSeenLocation { get; }

    event EventHandler<MvxValueEventArgs<MvxLocationPermission>> OnPermissionChanged;
}

使用方式和Accelerometer類似,就不詳述了。

Messenger

Messenger外掛提供了基於記憶體的元件間基於訊息的pub/sub功能。非常有用的一個外掛。nuget package:MvvmCross.Plugins.Messenger。這是一個純PCL外掛,沒有平臺特定程式碼。實現了IMvxMessenger介面:

public interface IMvxMessenger
{
    MvxSubscriptionToken Subscribe<TMessage>(Action<TMessage> deliveryAction, MvxReference reference = MvxReference.Weak, string tag = null) where TMessage : MvxMessage;
    MvxSubscriptionToken SubscribeOnMainThread<TMessage>(Action<TMessage> deliveryAction, MvxReference reference = MvxReference.Weak, string tag = null) where TMessage : MvxMessage;

    MvxSubscriptionToken SubscribeOnThreadPoolThread<TMessage>(Action<TMessage> deliveryAction, MvxReference reference = MvxReference.Weak, string tag = null) where TMessage : MvxMessage;

    void Unsubscribe<TMessage>(MvxSubscriptionToken mvxSubscriptionId) where TMessage : MvxMessage;

    bool HasSubscriptionsFor<TMessage>() where TMessage : MvxMessage;

    int CountSubscriptionsFor<TMessage>() where TMessage : MvxMessage;

    bool HasSubscriptionsForTag<TMessage>(string tag) where TMessage : MvxMessage;

    int CountSubscriptionsForTag<TMessage>(string tag) where TMessage : MvxMessage;

    IList<string> GetSubscriptionTagsFor<TMessage>() where TMessage : MvxMessage;

    void Publish<TMessage>(TMessage message) where TMessage : MvxMessage;

    void Publish(MvxMessage message);

    void Publish(MvxMessage message, Type messageType);

    void RequestPurge(Type messageType);

    void RequestPurgeAll();
}

Network

Network外掛本來只是設計來檢測某個網路主機是否能連通。結果,功能被熱心網友不斷擴充,就成了一個輕量級的REST Http Client。nuget package:MvvmCross.Plugins.Network。它提供了下面這些介面的實現:

public interface IMvxReachability
{
    bool IsHostReachable(string host);
}

public interface IMvxRestClient
{
    void ClearSetting(string key);

    void SetSetting(string key, object value);

    IMvxAbortable MakeRequest(MvxRestRequest restRequest, Action<MvxRestResponse> successAction, Action<Exception> errorAction);
    IMvxAbortable MakeRequest(MvxRestRequest restRequest, Action<MvxStreamRestResponse> successAction, Action<Exception> errorAction);

    Task<MvxRestResponse> MakeRequestAsync(MvxRestRequest restRequest, CancellationToken cancellationToken = default(CancellationToken));
    Task<MvxStreamRestResponse> MakeStreamRequestAsync(MvxRestRequest restRequest, CancellationToken cancellationToken = default(CancellationToken));
}

public interface IMvxJsonRestClient
{
    Func<IMvxJsonConverter> JsonConverterProvider { get; set; }

    IMvxAbortable MakeRequestFor<T>(MvxRestRequest restRequest, Action<MvxDecodedRestResponse<T>> successAction, Action<Exception> errorAction);

    Task<MvxDecodedRestResponse<T>> MakeRequestForAsync<T>(MvxRestRequest restRequest, CancellationToken cancellationToken = default(CancellationToken));
}

PhoneCall

PhoneCall外掛自然是用來打電話的。nuget package:MvvmCross.Plugins.PhoneCall。實現了IMvxPhoneCallTask介面:

public interface IMvxPhoneCallTask
{
    void MakePhoneCall(string name, string number);
}

PictureChooser

PictureChooser用來從相簿選照片,或者用相機拍照。nuget package:MvvmCross.Plugins.PictureChooser。實現了IMvxPictureChooserTask介面:

public interface IMvxPictureChooserTask
{
    void ChoosePictureFromLibrary(int maxPixelDimension, int percentQuality, Action<Stream> pictureAvailable, Action assumeCancelled);

    void TakePicture(int maxPixelDimension, int percentQuality, Action<Stream> pictureAvailable, Action assumeCancelled);
}

簡單的使用程式碼如下:

var task = Mvx.Resolve<IMvxPictureChooserTask>();
task.ChoosePictureFromLibrary(500, 90,
       stream => {
           // use the stream
           // expect the stream to be disposed after immediately this method returns.
       },
       () => {
           // perform any cancelled operation
       });

Share

Share外掛用來發表分享。nuget package:MvvmCross.Plugins.Share。實現了IMvxShareTask介面:

public interface IMvxShareTask
{
    void ShareShort(string message);
    void ShareLink(string title, string message, string link);
}

SQLite

SQLite外掛是又一款必備外掛,用來訪問Sqlite資料庫。nuget package:MvvmCross.Plugin.SQLitePCL。實現了IMvxSqliteConnectionFactory介面:

public interface IMvxSqliteConnectionFactory
{
    SQLiteConnection GetConnection(string databaseName, bool prefixPlatformPath = true);
    SQLiteConnection GetConnection(SqLiteConfig config, bool prefixPlatformPath = true);
    SQLiteAsyncConnection GetAsyncConnection(string databaseName, bool prefixPlatformPath = true);
    SQLiteAsyncConnection GetAsyncConnection(SqLiteConfig config, bool prefixPlatformPath = true);
}

WebBrowser

WebBrowser外掛呼叫外部瀏覽器顯示一個頁面。nuget package:MvvmCross.Plugins.WebBrowser。實現了IMvxWebBrowserTask介面:

public interface IMvxWebBrowserTask
{
    void ShowWebPage(string url);
}

MvvmCross提供的官方外掛,推薦的就這些了。貌似還有點不過癮,好像很多期望的必備功能還沒看到?下面來看看社群的貢獻。

第三方外掛

Settings

Settings外掛提供了一個通用方案,用來持久化儲存key/value鍵值對到各平臺預設的App本地配置檔案。nuget package:Cheesebaron.MvxPlugins.Settings。實現了ISettings介面:

public interface ISettings
{
    /// <param name="roaming">Roam settings (only for WindowsCommon)</param>
    
    T GetValue<T>(string key, T defaultValue = default(T), bool roaming = false);
    bool AddOrUpdateValue<T>(string key, T value = default(T), bool roaming = false);
    bool DeleteValue(string key, bool roaming = false);
    bool Contains(string key, bool roaming = false);
    bool ClearAllValues(bool roaming = false);
}

DeviceInfo

DeviceInfo外掛支援獲取包括裝置解析度,裝置id,韌體版本,記憶體大小等等裝置資訊。nuget package:Cheesebaron.MvxPlugins.DeviceInfo。實現了IDeviceInfo和IDisplay介面:

public interface IDeviceInfo
{
    string DeviceId { get; }
    string Name { get; }
    string FirmwareVersion { get; }
    string HardwareVersion { get; }
    string Manufacturer { get; }
    string LanguageCode { get; }
    double TimeZoneOffset { get; }
    string TimeZone { get; }
    Orientation Orientation { get; }
    long TotalMemory { get; }
    bool IsTablet { get; }
    DeviceType DeviceType { get; }
}

public interface IDisplay
{
    int Height { get; }
    int Width { get; }
    double Xdpi { get; }
    double Ydpi { get; }
    double Scale { get; }
}

Connectivity

Connectivity外掛返回當前裝置是否聯網,當前使用WIFI還是行動網路。nuget package:Cheesebaron.MvxPlugins.Connectivity。實現了IConnectivity介面:

public interface IConnectivity: INotifyPropertyChanged
{
    bool IsConnected { get; }
    bool IsWifi { get; }
    bool IsCellular { get; }
    Task<bool> GetHostReachableAsync(string host, CancellationToken token = default(CancellationToken));
}

SMS

SMS插用來發送簡訊。nuget package:Cheesebaron.MvxPlugins.SMS。實現了ISmsTask介面:

public interface ISmsTask
{
    void SendSMS(string body, string phoneNumber);
}

SecureStorage

SecureStorage插用使用者儲存敏感資料key/value鍵值對到平臺特定的安全資料儲存,比如Keychain,Password Vault等。nuget package:Beezy.MvvmCross.Plugins.SecureStorage。實現了IMvxProtectedData介面:

public interface IMvxProtectedData
{
    void Protect(string key, string value);
    string Unprotect(string key);
    void Remove(string key);
}

InfiniteScrollPlugin

InfiniteScrollPlugin插用提供了一個能夠根據指定的資料來源,一直向下滾動分頁顯示資料的能力。nuget package:Sequence.Plugins.InfiniteScroll。實現了IIncrementalCollectionFactory介面。典型的示例可以參見這裡

Fingerprint

Fingerprint提供指紋識別驗證支援。nuget package:MvvmCross.Plugins.Fingerprint。實現了IFingerprint介面:

    Task<FingerprintAvailability> GetAvailabilityAsync();
    Task<bool> IsAvailableAsync();
    Task<FingerprintAuthenticationResult> AuthenticateAsync(string reason, CancellationToken cancellationToken = default(CancellationToken));
    Task<FingerprintAuthenticationResult> AuthenticateAsync(AuthenticationRequestConfiguration authRequestConfig, CancellationToken cancellationToken = default(CancellationToken));

呼叫IFingerprint介面的示例:

var fpService = Mvx.Resolve<IFingerprint>(); // or use dependency injection and inject IFingerprint

var result = await fpService.AuthenticateAsync("Prove you have mvx fingers!");
if (result.Authenticated)
{
    // do secret stuff :)
}
else
{
    // not allowed to do secret stuff :(
}

UserInteraction

UserInteraction外掛實現了最常用的幾個UserDialogs,包括:Alert,Confirm和Input。nuget package:Chance.MvvmCross.Plugins.UserInteraction。它實現了IUserInteraction介面:

public interface IUserInteraction
{
    void Confirm(string message, Action okClicked, string title = null, string okButton = "OK", string cancelButton = "Cancel");
    void Confirm(string message, Action<bool> answer, string title = null, string okButton = "OK", string cancelButton = "Cancel");
    Task<bool> ConfirmAsync(string message, string title = "", string okButton = "OK", string cancelButton = "Cancel");

    void Alert(string message, Action done = null, string title = "", string okButton = "OK");
    Task AlertAsync(string message, string title = "", string okButton = "OK");

    void Input(string message, Action<string> okClicked, string placeholder = null, string title = null, string okButton = "OK", string cancelButton = "Cancel", string initialText = null);
    void Input(string message, Action<bool, string> answer, string placeholder = null, string title = null, string okButton = "OK", string cancelButton = "Cancel", string initialText = null);
    Task<InputResponse> InputAsync(string message, string placeholder = null, string title = null, string okButton = "OK", string cancelButton = "Cancel", string initialText = null);

    void ConfirmThreeButtons(string message, Action<ConfirmThreeButtonsResponse> answer, string title = null, string positive = "Yes", string negative = "No", string neutral = "Maybe");
    Task<ConfirmThreeButtonsResponse> ConfirmThreeButtonsAsync(string message, string title = null, string positive = "Yes", string negative = "No", string neutral = "Maybe");
}

User Dialogs

User Dialogs嚴格來說並不是一個標準的MvvmCross外掛。但是它提供了相比上面的UserInteraction更豐富的User Dialogs功能,所以,有需要的朋友也可以看一下。nuget package: Acr.UserDialogs。它可以和MvvmCrossy一起工作,但是沒有follow MvvmCross外掛自動初始化機制,因此,需要特別配置。引用package之後,需要在App類中註冊IUserDialog到Mvx的IoC容器:

Mvx.RegisterSingleton<IUserDialogs>(() => UserDialogs.Instance);

同時,對於Droid專案(iOS專案不需要),還必須在MvxFormsApplicationActivity類的OnCreate()方法裡,執行下面的初始化程式碼:

UserDialogs.Init(this);

然後,就可以在任意Command裡呼叫IUserDialogs介面的方法彈出Dialogs了。IUserDialogs介面支援下面這些Dialogs方法:

public interface IUserDialogs
{
    IDisposable Alert(string message, string title = null, string okText = null);
    IDisposable Alert(AlertConfig config);
    Task AlertAsync(string message, string title = null, string okText = null, CancellationToken? cancelToken = null);
    Task AlertAsync(AlertConfig config, CancellationToken? cancelToken = null);

    IDisposable ActionSheet(ActionSheetConfig config);
    Task<string> ActionSheetAsync(string title, string cancel, string destructive, CancellationToken? cancelToken = null, params string[] buttons);

    IDisposable Confirm(ConfirmConfig config);
    Task<bool> ConfirmAsync(string message, string title = null, string okText = null, string cancelText = null, CancellationToken? cancelToken = null);
    Task<bool> ConfirmAsync(ConfirmConfig config, CancellationToken? cancelToken = null);

    IDisposable DatePrompt(DatePromptConfig config);
    Task<DatePromptResult> DatePromptAsync(DatePromptConfig config, CancellationToken? cancelToken = null);
    Task<DatePromptResult> DatePromptAsync(string title = null, DateTime? selectedDate = null, CancellationToken? cancelToken = null);

    IDisposable TimePrompt(TimePromptConfig config);
    Task<TimePromptResult> TimePromptAsync(TimePromptConfig config, CancellationToken? cancelToken = null);
    Task<TimePromptResult> TimePromptAsync(string title = null, TimeSpan? selectedTime = null, CancellationToken? cancelToken = null);

    IDisposable Prompt(PromptConfig config);
    Task<PromptResult> PromptAsync(string message, string title = null, string okText = null, string cancelText = null, string placeholder = "", InputType inputType = InputType.Default, CancellationToken? cancelToken = null);
    Task<PromptResult> PromptAsync(PromptConfig config, CancellationToken? cancelToken = null);

    IDisposable Login(LoginConfig config);
    Task<LoginResult> LoginAsync(string title = null, string message = null, CancellationToken? cancelToken = null);
    Task<LoginResult> LoginAsync(LoginConfig config, CancellationToken? cancelToken = null);

    IProgressDialog Progress(ProgressDialogConfig config);
    IProgressDialog Loading(string title = null, Action onCancel = null, string cancelText = null, bool show = true, MaskType? maskType = null);
    IProgressDialog Progress(string title = null, Action onCancel = null, string cancelText = null, bool show = true, MaskType? maskType = null);

    void ShowLoading(string title = null, MaskType? maskType = null);
    void HideLoading();

    void ShowImage(IBitmap image, string message, int timeoutMillis = 2000);
    void ShowSuccess(string message, int timeoutMillis = 2000);
    void ShowError(string message, int timeoutMillis = 2000);

    IDisposable Toast(string title, TimeSpan? dismissTimer = null);
    IDisposable Toast(ToastConfig cfg);
}

AudioPlay

比較遺憾的是沒有看到支援音樂播放(比如播放線上或本地的mp3/wav)的外掛。這個應該是大多數App都需要的功能。搜尋了一些網上的實現方案,先給需要的朋友做個參考,要不下次咱把它改造成標準的MvvmCross外掛?

  • https://github.com/srkrathore/AudioPlayEx
  • http://www.cnblogs.com/fbsk/archive/2012/02/10/2345128.html
  • http://blog.endpoint.com/2011/03/api-gaps-android-mediaplayer-example.html

2016-10-23 Update: 新增一些非MvvmCross,但是Xamarin下的通用第三方元件:

  • Xamarin-Forms-Labs - 看上去是Xamarin界最大的一個第三方元件庫,包含了大量UI和Service等型別的好東西,元件列表太長了,不貼在這裡,大家可以點過去看。
  • DLToolkit.Forms.Controls - DL Toolkit提供的幾個非常酷的元件,包括圖片轉換、增強的ListView和tag標籤功能等。
  • DevExpress-Grid - 老牌大廠DevExpress出的Xamarin Forms資料表格控制元件,功能強大,竟然完全免費?!

暫時就這些了。如果您發現有別的優秀外掛,歡迎推薦,我也會持續補充進來。

相關推薦

Xamarin Forms開發框架MvvmCross外掛精選

在前兩篇老司機學Xamarin系列中,簡單介紹了Xamarin開發環境的搭建以及Prism和MvvmCross這兩個開發框架。不同的框架,往往不僅僅使用不同的架構風格,同時社群活躍度不同,各種功能模組和外掛數量也會有巨大差別。架構風格的好壞,屬於仁者見仁,但功能模組和外掛的好壞多寡,卻實實在在體現了社群的力量

張高興的 Xamarin.Forms 開發筆記:為 Android 與 iOS 引入 UWP 風格的漢堡菜單 ( MasterDetailPage )

操作 using eat stp 取消 height 新建 屬性 turn   所謂 UWP 樣式的漢堡菜單,我曾在“張高興的 UWP 開發筆記:漢堡菜單進階”裏說過,也就是使用 Segoe MDL2 Assets 字體作為左側 Icon,並且左側使用填充顏色的矩形用來表示

Xamarin.Forms 開發IOS、Android、UWP應用

windows 開發項目 alt ive 快速 需要 預覽 開發 aml C#語言特點,簡單、快速、高效。本次我們通過C#以及Xaml來做移動開發。 1.開發工具visual studio 2015或visual studio 2017。當然visual studio 20

最新h5牛牛平臺遊戲開發框架架構

內存 cal 引用 構造 autot auto 新的 clas 線程同步 Q1446595067官網:h5.haozibbs.com或http:\\www.aqbaa.cn 現在來和大家分享下怎麽架構和實現框架來滿足棋牌遊戲需求的。 一、原型 符合棋牌項目框架,快速換皮

spring 03-Spring開發框架控制反轉

控制反轉原理 測試介面程式 package cn.liang.service; public interface IMessageService { public String getInfo() ; } package cn.liang.service.impl; import cn.

我的開發框架ORM框架

今天我想分享一下我自己的ORM框架,雖然談不是很好,但我個人認為還是蠻好用的,跟大家分享交流一下。 首先說說我對現在主流的ORM框架的一些看法: 優點: 讓程式設計師不再關注資料庫細節,專心在業務邏輯上,程式設計師可以不懂資料庫就可以開發系統。 讓資料庫遷移變的非常方便,如果系統需要更改使用的資料

PHP開發框架YII框架學習——碾壓ThinkPHP不是夢

  前  言 JRedu  程式猿是一種慵懶的生物!能少敲一行程式碼,絕對不會多敲一個字元!所以,越來越多的開發框架應運而生,在幫助我們完成功能的同時,極大程度上也幫我們節省了人力物力,而且也提高了系統的安全效能。  而PHP,號稱“世界上最好用的程式語言”!自然也擁有一大群的“腦殘粉”,讓諸多的PHP程式

Winform開發框架字典管理模組的更新,附上最新2013年全國最新縣及縣以上行政區劃程式碼sql指令碼

在很多專案裡面,字典管理是必備的專案模組,而這個又是比較通用的功能,因此可以單獨做成一個通用字典管理,例如這個模組,可以通過整合的方式,使用在我的《Winform開發框架》、《WCF開發框架》、《混合式開發框架》中,這樣可以避免程式碼的重複維護管理,對企業來說,也可以更好管理核心的程式碼,實現統一的版本更替。

Winform開發框架Office Ribbon介面

在前面幾篇文章介紹我的Winform框架隨筆文章,包括有《》、《》、《》,其中Winform開發框架之終極應用是集眾多功能與一身,提供綜合一站式、整體性的傳統應用系統的開發框架,在此基礎上開發新的業務系統,開發工作則是事半功倍,而且提供了高效、統一的介面佈局以及支援多種資料庫的資料訪問層支援,提供了基於大量

微服務-開發框架springboot by

1.0 size src main方法 info 關於 我們 com 可讀性 目錄 一、關於springboot 二、springboot的實踐 2.1發布一個rest的api 2.2端點 一、關於springboot 由來:spring1.0-2.0用

[js高手路]從零開始打造一個javascript開源框架gdom與外掛開發免費視訊教程連載中

具體課程目錄: 1,課程安排【視訊已上傳】 2,gdom框架使用方法【視訊已上傳】 3,變數提升【視訊已上傳】 4,變數提升之同名變數,函式宣告,表示式的提升規則【視訊已上傳】 5,this關鍵字專題詳解【視訊已上傳】 6,物件在記憶體中的表現形式【視訊已上傳】 7,圖解原型物件與隱式原

(轉)基於MVC4+EasyUI的Web開發框架形成旅--MVC控制器的設計

cli dex txt strip -1 function 特殊 remote 文章 http://www.cnblogs.com/wuhuacong/p/3284628.html 自從上篇《基於MVC4+EasyUI的Web開發框架形成之旅--總體介紹》總體性的概括,得

C++開發人臉性別識別教程(8)——搭建MFC框架讀取目錄信息

tail 分享 itemid readdir 文件路徑 alloc tle word 運行   在上一篇博客中我們已經繪制了MFC界面,在這篇博客中我們將加入響應代碼,為MFC框架加入一個最主要的功能:打開一個目錄。   一、加入相關頭文件   這裏

菜鳥的Xamarin.Forms前行路——按鈕的按下擡起事件的監控(可擴展至其他事件)

override 點擊 names div prot tco nco nbsp 容易 提問:監控按鈕的點擊事件,可以通過按鈕的Click事件,或者Command綁定,那麽如何監控按鈕的按下與擡起,或者移動,長按,雙擊等事件? 解決方法:各個平臺自定義渲染依賴註入. 共享項目

菜鳥的Xamarin.Forms前行路——實現按鈕的字體圖標(可擴展)

方法 所有 blank render 背景圖片 list cer 元素 ren 在實際的APP中,帶有圖標的按鈕用到地方還是蠻多的,字體圖標往往能更快更生動的傳達信息,並且相對於背景圖片,字體圖標也有著絕對的優勢,所以實現按鈕的字體圖標是值得嘗試的. 實現方法:各平臺自定義

android mvp高速開發框架介紹(dileber使用圖片下載工具)

net com 例如 下載 pop bug span 介紹 launcher 這幾天忙著工作~ 今天抽時間又把框架的bug處理了一下~~並且把volley的源代碼改

Python面試題前端和框架155問 python開發

python編程 python開發 python自動化 1. 談談你對http協議的認識。2. 談談你對websocket協議的認識。3. 什麽是magic string ?4. 如何創建響應式布局?5. 你曾經使用過哪些前端框架?6. 什麽是ajax請求?並使用jQuery和XMLHttpReq

J2EE分布式框架開發環境部署(上)

springmvc mybatis dubbo j2ee spring 環境搭建: 1.環境準備 1.開發工具: Eclipse IDE(建議使用高一點的版本) 2.JDK版本:JDK1.7 3.項目管理: Maven3.1.1 2.安裝步驟 1.安裝jdk1.7並配置環境變量(相信大家都

J2EE分布式框架開發環境部署(下)

mybatis springmvc 本篇繼續為大家講解J2EE分布式框架的開發環境部署: Eclipse中配置maven安裝目錄和Setting文件加載的本地庫目錄 11.導入Maven項目 File》Import》Existing Maven Projects》下一步 選擇你本地的maven項目

JEESZ分布式框架開發環境部署(上)

說明 設置 package 知識 公司 信息 iso div 輸入 環境搭建: 1.環境準備 1.開發工具: Eclipse IDE(建議使用高一點的版本) 2.JDK版本:JDK1.7 3.項目管理: Maven3.1.1 2.安裝步驟 1.安裝jdk1.7並配置環境變量