هل هناك طريقة آمنة للتنقل بين الشاشات في هاتف ويندوز?

StackOverflow https://stackoverflow.com//questions/20004086

سؤال

أبحث عن طريقة للتنقل بين الشاشات في تطبيقي.أساسا ما رأيته حتى الآن يتكون من تمرير سلسلة أوري إلى نافيغاتيونسرفيس ، كاملة مع معلمات سلسلة الاستعلام.، على سبيل المثال.

NavigationService.Navigate(new Uri("/MainPage.xaml?selectedItem=" +bookName.Id, UriKind.Relative));

أنا لست حريصا حقا على هذا على الرغم من أنه في نهاية المطاف لأنه يتطلب سلاسل سحرية ، وأنها يمكن أن تؤدي إلى مشاكل على الطريق.

من الناحية المثالية ، سأقوم فقط بإنشاء مثيل للفئة التي أريد الانتقال إليها ، وتمرير المعلمات كوسائط إلى المنشئ.هل هذا ممكن?لو ذلك, كيف?

هل كانت مفيدة؟

المحلول

بينما سيتعين على التنقل الفعلي استخدام السلاسل في النهاية، يمكنك إنشاء أو استخدام غلاف آمن للكتابة.

أود أن أقترح النظر في كاليبورن مايكرو حتى لو كنت تستخدمه فقط لنوع التنقل الآمن.هنا مقتطف من البرنامج التعليمي حول استخدامه في WP8:

تدعم خدمة التنقل التي تأتي مع مجموعة الأدوات شاهد النموذج أولا يقترب:بدلاً من الإعلان عن عنوان URL للصفحة التي نريد نقل المستخدم إليها (وهذا هو النهج القياسي)، نعلن عن نموذج ViewModel الذي نريد عرضه. ستهتم الخدمة بإنشاء عنوان URL الصحيح وستعرض العرض المرتبط بنموذج العرض.

بدلا من ذلك يمكنك أن تنظر إلى ويندوز فون إم في سي والذي يحتوي أيضًا على نوع من التنقل الآمن.قد تتمكن أيضًا من سحب رمز التنقل لاستخدامه بنفسك نظرًا لأنه مرخص بموجب MS-PL.

نصائح أخرى

في الأساس ، لا ، ليس هذا مدمج.المعلمات المعقدة مثل حالات إيريبوسيتوري هي ، للأسف ، أبعد من قدرة مرافق الملاحة في سيلفرلايت;وعادة ما تستخدم شكلا من أشكال الحاويات أوك للتعامل مع تلك.يتم تسلسل معلمات بوكو أبسط بسهولة إلى سلسلة ، ولكن هذا لا يزال يتطلب سلاسل سحرية وتحليل سلسلة الاستعلام اليدوي.

ومع ذلك ، يمكنك بسهولة بناء شيء نوعآمن نفسك.على سبيل المثال ، وهنا نهجي.

بالنسبة لبيانات المعلمة ، لدي فئة أسميها 'إضافات' ، والتي يلتف Dictionary<string, object> مع طرق مثل GetBool(string), GetInt32(string), ، إلخ.، ولها طريقة مصنع ثابتة CreateFromUri(Uri);هذا جيد بما فيه الكفاية لأغراضي.

يمكنني استخدام هذا بالاقتران مع التنقل الآمن من النوع.أنا حقا أحب نمط مففم ، وكل من صفحاتي لديه فيوموديل تغليف تقريبا كل المنطق.العلاقة واحد إلى واحد من الصفحة إلى فيوموديل يجعل هذا الأخير مفتاح التنقل المثالي.هذا ، جنبا إلى جنب مع السمات والتفكير ، يعطينا حلا بسيطا:

public class NavigationTargetAttribute : Attribute
{
    private readonly Type target;

    public ViewModelBase Target
    {
        get { return target; }
    }

    public NavigationTargetAttribute(Type target)
    {
        this.target = target;
    }
}

وضع واحد من هذه على كل من صفحاتك ، مع نوع فيوموديل الصحيح.

[NavigationTarget(typeof(LoginViewModel))]
public class LoginPage : PhoneApplicationPage
{ ... }

ثم ، في فئة سينغلتون نافيغاتيونماناجر سقو ، يمكنك القيام به:

GetType().Assembly
    .GetTypes()
    .Select(t => new { Type = t, Attr = t.GetCustomAttributes(false).FirstOrDefault(attr => attr is NavigationTargetAttribute) })
    .Where(t => t.Attr != null);

وتماما مثل ذلك ، لديك مجموعة من كل نوع للملاحة في التطبيق الخاص بك.من هناك ، انها ليست أكثر من ذلك بكثير العمل لوضعها في القاموس ، على سبيل المثال.إذا كنت تتبع اتفاقية للمكان الذي وضعت صفحاتك ، يمكنك (على سبيل المثال) ترجمة بين نوع و أوري بسهولة تامة...على سبيل المثال, new Uri("/Pages/" + myPageType.Name + ".xaml", UriKind.Relative).انها ليست أكثر من ذلك بكثير لإضافة دعم لمعلمات الاستعلام.وأخيرا ، سوف ينتهي بك الأمر مع طريقة ، مثل ذلك:

public void Navigate(Type target, Extras extras)
{
    Type pageType;
    if (navigationTargets.TryGetValue(target, out pageType))
    {
        var uri = CreateUri(pageType, extras);
        navigationService.NavigateTo(uri);
    }

    // error handling here
}

أخيرا ، في الصفحة OnNavigatedTo الطريقة ، أفعل شيئا مثل:

var extras = Extras.CreateFromUri(e.Uri);
((ViewModelBase) DataContext).OnNavigatedTo(extras);

هذا ، أخيرا ، يعطي مظهرا من التنقل المكتوب بشدة.هذا هو نهج العظام العارية;من أعلى رأسي ، يمكن تحسين ذلك عن طريق إضافة المعلمات المطلوبة في سمة التنقل والتحقق من صحتها في وقت التنقل.كما أنه لا يدعم أنواعا أكثر تعقيدا من التنقل ، حيث تحدد قيمة وسيطات التنقل الوجهة النهائية.ومع ذلك ، فإن هذا يناسب حالة الاستخدام الخاصة بي بنسبة 90 ٪ - ربما ستعمل من أجلك أيضا.

هناك بالتأكيد بعض التفاصيل التي تم حذفها هنا ، مثل كيفية الحصول على مثيل NavigationService - يمكنني عمل عينة أكثر اكتمالا في وقت لاحق الليلة ، لكن هذا يجب أن يكون كافيا للبدء.

يمكنك استخدام PhoneApplicationService.State

وهو Dictionary<String,Object>

PhoneApplicationService.State يستخدم عادة في تومبستونينغ لتخزين الحالة الراهنة للتطبيق.ومع ذلك ، يمكن استخدامه لتمرير البيانات بسهولة بين الصفحات.

وثائق مسن

يتم إلغاء تنشيط تطبيقات هاتف ويندوز عندما ينتقل المستخدم إلى تطبيق آخر.عندما يعود المستخدم إلى التطبيق ، من خلال باستخدام زر الرجوع أو عن طريق إكمال مهمة قاذفة أو منتقي ، فإن يتم إعادة تنشيط التطبيق.تطبيق يمكن تخزين عابرة حالة التطبيق في قاموس الدولة في معالج ل حدث معطل.في معالج الأحداث المنشط ، يمكن للتطبيق استخدم القيم المخزنة في قاموس الحالة لتطبيق عابر الدولة.

أساسا ما كنت ستفعل هو

PhoneApplicationService.State.add(selectedName,yourobjectInstance);
NavigationService.Navigate((new Uri("/MainPage.xaml?selectedItem="+selectedName,UriKind.Relative));

ثم في طريقة التنقل الخاصة بك أيضا يمكنك استردادها

YourObject yourObjectInstance;
var yourObj = PhoneApplicationService.State["yourObjectName"];
yourObjectInstance = yourObj is YourObject ? (yourObj as YourObject) : null;

فيما يلي نظرة أكثر عمقا حول كيفية استخدام هذه الميزة

وف يدعم التنقل إلى كائن تم إنشاؤه بالفعل ، ولكن وب 8 يفتقر إلى ذلك Navigate الزائد.

إذا كنت لا ترغب في الصعب رمز زمل الصفحة أوريس ، يمكنك يمكنك استخدام وظيفة المساعد التالية (قليلا القذرة) للحصول على .زمل الموارد أوري من بعض الطبقة.

static Uri GetComponentUri<T>() where T : DependencyObject, new() {
    return BaseUriHelper.GetBaseUri(new T());
}

ثم يمكنك تعديل هذا الرابط والانتقال إليه:

var baseUri = GetComponentUri<SomePage>(); //Uri="pack://application:,,,/MyProject;component/MainWindow.xaml"
var pageUri = new UriBuilder(baseUri) { Query = "selectedItem=" + bookName.Id };
NavigationService.Navigate(pageUri);

الحل الذي لدينا يعمل بشكل جيد:
1. لا تستخدم سلاسل الاستعلام في Page Uris، هذا يتعارض تمامًا مع MVVM حيث يجب أن يعرض العرض الأشياء فقط، ولكن المنطق الفعلي لتحميل العناصر وتحديدها موجود في ViewModel.
2.يخلق فئة مع أسماء صفحة const وعندما تريد التنقل، فقط استخدم هذا:

public static class P
{
    public const string ArticlePage = "/Pages/ArticlePage.xaml";
    public const string OnlineSectionPage = "/Pages/OnlineSectionPage.xaml";
    public const string GalleryPage = "/Pages/GalleryPage.xaml";
    ...
}

// in our viewModel
NavigationService.Navigate(P.ArticlePage);

// In navigation service
public void Navigate(string pagePath)
{
    if (EnsureMainFrame())
    {
        mainFrame.Navigate(new Uri(pagePath, UriKind.RelativeOrAbsolute));
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top