2016-04-17 7 views
7

मैं एक ऐप लिख रहा हूं जो अलग-अलग दस्तावेजों को अपनी खिड़की में संपादित करने के लिए कई विचारों को चलाने में सक्षम होना चाहिए। मैंने कुछ कोड लिखा है जो काम करता है, लेकिन मुझे इसके साथ कुछ समस्याएं आ रही हैं। मैंने जो कोड लिखा है वह माइक्रोसॉफ्ट (https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/MultipleViews) द्वारा प्रदान किए गए एकाधिक दृश्य नमूने पर आधारित है।कई विचारों के साथ यूडब्ल्यूपी समस्याएं

मेरे पास मुख्य रूप से दो समस्याएं हैं। पहला यह है कि अगर मैं मुख्य दृश्य बंद करता हूं, तो यह पहली विंडो है जो एप्लिकेशन लॉन्च होने पर खुला था, फिर मैं ऐप टाइल में क्लिक करके या संबंधित फ़ाइल प्रकार खोलकर कोई नया दृश्य/विंडो नहीं खोल सकता, जब तक कि मैं बंद नहीं करता सभी विचार/खिड़कियां और ऐप को फिर से लॉन्च करें। दूसरा, यह है कि जब मैं MainPage.xaml.cs से एक नया दृश्य/विंडो खोलने का प्रयास करता हूं, तो ऐप बस क्रैश हो जाता है।

sealed partial class App : Application 
{ 
    //I use this boolean to determine if the application has already been launched once 
    private bool alreadyLaunched = false; 

    public ObservableCollection<ViewLifetimeControl> SecondaryViews = new ObservableCollection<ViewLifetimeControl>(); 
    private CoreDispatcher mainDispatcher; 
    public CoreDispatcher MainDispatcher 
    { 
     get 
     { 
      return mainDispatcher; 
     } 
    } 

    private int mainViewId; 
    public int MainViewId 
    { 
     get 
     { 
      return mainViewId; 
     } 
    } 

    public App() 
    { 
     this.InitializeComponent(); 
     this.Suspending += OnSuspending; 
    } 

    protected override async void OnLaunched(LaunchActivatedEventArgs e) 
    { 
     Frame rootFrame = Window.Current.Content as Frame; 

     if (rootFrame == null) 
     { 
      rootFrame = new Frame(); 

      rootFrame.NavigationFailed += OnNavigationFailed; 

      if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) 
      { 
       //TODO: Load state from previously suspended application 
      } 

      // Place the frame in the current Window 
      Window.Current.Content = rootFrame; 
     } 

     if (rootFrame.Content == null) 
     { 
      alreadyLaunched = true; 
      rootFrame.Navigate(typeof(MainPage), e.Arguments); 
     } 
     else if(alreadyLaunched) 
     { 
      var selectedView = await createMainPageAsync(); 
      if (null != selectedView) 
      { 
       selectedView.StartViewInUse(); 
       var viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(
        selectedView.Id, 
        ViewSizePreference.Default, 
        ApplicationView.GetForCurrentView().Id, 
        ViewSizePreference.Default 
        ); 

       await selectedView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
       { 
        var currentPage = (MainPage)((Frame)Window.Current.Content).Content; 
        Window.Current.Activate(); 
       }); 

       selectedView.StopViewInUse(); 
      } 
     } 
     // Ensure the current window is active 
     Window.Current.Activate(); 
    } 

    protected override async void OnFileActivated(FileActivatedEventArgs args) 
    { 
     base.OnFileActivated(args); 

     if (alreadyLaunched) 
     { 
      //Frame rootFrame = Window.Current.Content as Frame; 
      //((MainPage)rootFrame.Content).OpenFileActivated(args); 
      var selectedView = await createMainPageAsync(); 
      if (null != selectedView) 
      { 
       selectedView.StartViewInUse(); 
       var viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(
        selectedView.Id, 
        ViewSizePreference.Default, 
        ApplicationView.GetForCurrentView().Id, 
        ViewSizePreference.Default 
        ); 

       await selectedView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
       { 
        var currentPage = (MainPage)((Frame)Window.Current.Content).Content; 
        Window.Current.Activate(); 
        currentPage.OpenFileActivated(args); 
       }); 

       selectedView.StopViewInUse(); 
      } 
     } 
     else 
     { 
      Frame rootFrame = new Frame(); 
      rootFrame.Navigate(typeof(MainPage), args); 
      Window.Current.Content = rootFrame; 
      Window.Current.Activate(); 
      alreadyLaunched = true; 
     } 
    } 

    partial void Construct(); 
    partial void OverrideOnLaunched(LaunchActivatedEventArgs args, ref bool handled); 
    partial void InitializeRootFrame(Frame frame); 

    partial void OverrideOnLaunched(LaunchActivatedEventArgs args, ref bool handled) 
    { 
     // Check if a secondary view is supposed to be shown 
     ViewLifetimeControl ViewLifetimeControl; 
     handled = TryFindViewLifetimeControlForViewId(args.CurrentlyShownApplicationViewId, out ViewLifetimeControl); 
     if (handled) 
     { 
      var task = ViewLifetimeControl.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
      { 
       Window.Current.Activate(); 
      }); 
     } 
    } 

    partial void InitializeRootFrame(Frame frame) 
    { 
     mainDispatcher = Window.Current.Dispatcher; 
     mainViewId = ApplicationView.GetForCurrentView().Id; 
    } 

    bool TryFindViewLifetimeControlForViewId(int viewId, out ViewLifetimeControl foundData) 
    { 
     foreach (var ViewLifetimeControl in SecondaryViews) 
     { 
      if (ViewLifetimeControl.Id == viewId) 
      { 
       foundData = ViewLifetimeControl; 
       return true; 
      } 
     } 
     foundData = null; 
     return false; 
    } 

    private async Task<ViewLifetimeControl> createMainPageAsync() 
    { 
     ViewLifetimeControl viewControl = null; 
     await CoreApplication.CreateNewView().Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
     { 
      // This object is used to keep track of the views and important 
      // details about the contents of those views across threads 
      // In your app, you would probably want to track information 
      // like the open document or page inside that window 
      viewControl = ViewLifetimeControl.CreateForCurrentView(); 
      viewControl.Title = DateTime.Now.ToString(); 
      // Increment the ref count because we just created the view and we have a reference to it     
      viewControl.StartViewInUse(); 

      var frame = new Frame(); 
      frame.Navigate(typeof(MainPage), viewControl); 
      Window.Current.Content = frame; 
      // This is a change from 8.1: In order for the view to be displayed later it needs to be activated. 
      Window.Current.Activate(); 
      //ApplicationView.GetForCurrentView().Title = viewControl.Title; 
     }); 

     ((App)App.Current).SecondaryViews.Add(viewControl); 

     return viewControl; 
    } 

    void OnNavigationFailed(object sender, NavigationFailedEventArgs e) 
    { 
     throw new Exception("Failed to load Page " + e.SourcePageType.FullName); 
    } 

    private void OnSuspending(object sender, SuspendingEventArgs e) 
    { 
     var deferral = e.SuspendingOperation.GetDeferral(); 
     //TODO: Save application state and stop any background activity 
     deferral.Complete(); 
    } 

    //I call this function from MainPage.xaml.cs to try to open a new window 
    public async void LoadNewView() 
    { 
     var selectedView = await createMainPageAsync(); 
     if (null != selectedView) 
     { 
      selectedView.StartViewInUse(); 
      var viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(
       selectedView.Id, 
       ViewSizePreference.Default, 
       ApplicationView.GetForCurrentView().Id, 
       ViewSizePreference.Default 
       ); 

      await selectedView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
      { 
       var currentPage = (MainPage)((Frame)Window.Current.Content).Content; 
       Window.Current.Activate(); 
       currentPage.LoadNewFile(); 
      }); 

      selectedView.StopViewInUse(); 
     } 
    } 
} 

कोड मैं MainPage.xaml.cs से कोई नया दृश्य/खिड़की शुरू करने के लिए प्रयास करने के लिए उपयोग करें:

कोड है कि मैं App.xaml.cs में विचारों का प्रबंधन करने के लिए उपयोग निम्नलिखित है:

((App)App.Current).LoadNewView(); 

मैं कोशिश करते हैं और समझते हैं मुद्दा है क्या करने के लिए Microsoft प्रलेखन पढ़ रहा है, लेकिन मैं अभी भी समझ में नहीं आता कि कैसे वास्तव में एकाधिक दृश्य काम करते हैं, जैसे यदि अनुप्रयोग वर्ग हर बार instantiated मैं एक नया खोलने करना देखें/खिड़की।

मैं वास्तव में मदद की सराहना करता हूं।

+0

यह कोड 'currentPage.LoadNewFile(); 'मुख्य पृष्ठ के LoadNewFile का आह्वान कर रहा है। क्या आपने अपने Mainpage.xaml.cs में एक और 'LoadNewFile() 'विधि लिखा था? आप सभी कोड App.xaml.cs में क्यों डालते हैं? अपने सभी कोड अपलोड करने के लिए बेहतर है। –

+0

हां, मैंने LoadNewFile() विधि को मेरे MainPage.xaml.cs में लिखा था, और मैंने App.xaml.cs में कई दृश्यों के लिए सभी कोड डाले हैं इसलिए मुझे कोड को फिर से लिखना नहीं है, लेकिन मैंने इसे बनाने का प्रयास किया एक ही त्रुटियों के साथ मेरे MainPage.xaml.cs से नया दृश्य/विंडो। CoreApplication.CreateNewView()। Dispatcher.RunAsync (CoreDispatcherPriority) पर ऐप क्रैश हो जाता है।सामान्य,() => createMainPageAsync() विधि में चलता है, और अजीब चीज यह है कि यह विजुअल स्टूडियो –

+0

के बजाय एक और डीबगर खोलने का प्रयास करता है, उस स्थिति में, अपना पूरा कोड अपलोड करें, अन्यथा लोग त्रुटि कोड के बिना आपकी सहायता नहीं कर सकते हैं, गलतियों की जानकारी। –

उत्तर

2

मुझे अपनी समस्याओं का समाधान मिला है, और मैंने वास्तव में नमूना के साथ आने वाले व्यूलाइफटाइम नियंत्रण का उपयोग न करने का निर्णय लिया है।

समस्या आप यह है कि धागा

यहाँ चलाने के लिए अन्य विचार है कि अभी भी खुले हैं में से एक से Dispatcher.RunAsync() विधि का उपयोग करना होगा जब मुख्य दृश्य बंद कर दिया है है कि कोड मैं है

public bool isMainViewClosed = false; 
public ObservableCollection<CoreApplicationView> secondaryViews = new ObservableCollection<CoreApplicationView>(); 

//... 

protected override async void OnLaunched(LaunchActivatedEventArgs e) 
    { 
     Frame rootFrame = Window.Current.Content as Frame; 

     if (rootFrame == null) 
     { 
      rootFrame = new Frame(); 

      rootFrame.NavigationFailed += OnNavigationFailed; 

      if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) 
      { 
       //TODO: Load state from previously suspended application 
      } 
      Window.Current.Content = rootFrame; 
     } 

     if (rootFrame.Content == null) 
     { 
      alreadyLaunched = true; 
      rootFrame.Navigate(typeof(MainPage), e.Arguments); 
     } 
     else if(alreadyLaunched) 
     { 
    //If the main view is closed, use the thread of one of the views that are still open 
      if(isMainViewClosed) 
      { 
       int newViewId = 0; 
       await secondaryViews[0].Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
       { 
        var currentPage = (MainPage)((Frame)Window.Current.Content).Content; 
        Window.Current.Activate(); 
        currentPage.NewWindow(); 
        newViewId = ApplicationView.GetForCurrentView().Id; 
       }); 
       bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId); 
      } 
      else 
      { 
       CoreApplicationView newView = CoreApplication.CreateNewView(); 
       int newViewId = 0; 
       await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
       { 
        Frame frame = new Frame(); 
        frame.Navigate(typeof(MainPage), null); 
        Window.Current.Content = frame; 
        var currentPage = (MainPage)((Frame)Window.Current.Content).Content; 
        Window.Current.Activate(); 

        secondaryViews.Add(CoreApplication.GetCurrentView()); 
        newViewId = ApplicationView.GetForCurrentView().Id; 
       }); 
       bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId); 
      } 
     } 
     Window.Current.Activate(); 
    } 
-1

देखें नहीं है (अपने) लाइफटाइम दूर ... चियर्स,

int idCreate = 0; List<int> idSaved = new List<int>(); 
protected override async void OnLaunched(LaunchActivatedEventArgs e) 
{ 
    Frame rootFrame = Window.Current.Content as Frame; 
    if (rootFrame == null) 
    { 
     rootFrame = new Frame(); 
     rootFrame.NavigationFailed += OnNavigationFailed; 
     Window.Current.Content = rootFrame; 
    } 

    if (rootFrame.Content == null) 
    { 
     rootFrame.Navigate(typeof(MainPage), e.Arguments); 
     idSaved.Add(ApplicationView.GetForCurrentView().Id); 
    } 
    else 
    { 
     var create = CoreApplication.CreateNewView(); 
     await create.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
     { 
      var frame = new Frame(); 
      frame.Navigate(typeof(MainPage), e.Arguments); 
      Window.Current.Content = frame; 
      Window.Current.Activate(); 

      idCreate = ApplicationView.GetForCurrentView().Id; 
     }); 

     for(int i = idSaved.Count - 1; i >= 0; i--) 
      if (await ApplicationViewSwitcher.TryShowAsStandaloneAsync(
        idCreate, ViewSizePreference.UseMinimum, 
        idSaved[i], ViewSizePreference.UseMinimum) 
       ) break; 

     idSaved.Add(idCreate); 
    } 
    Window.Current.Activate(); 
} 
+3

यदि आप अपना उत्तर हटाना चाहते हैं, तो बस हटाएं बटन पर क्लिक करें। – FrankerZ

+0

@ फ्रैंकरजेड, अनियंत्रित उपयोगकर्ता अपने उत्तरों को हटा नहीं सकते हैं। –

7

वास्तव में उचित तरीके से अभी भी होने के लिए: किसी को भी है कि रुचि रखता है के लिए मेरे App.xaml.cs में बदल दिए हैंमुख्य बंद होने के बाद नई विंडो खोलने में सक्षम TryShowAsStandaloneAsync द्वारा प्रदत्त ओवरलोड में से एक का उपयोग करना है।

protected override async void OnLaunched(LaunchActivatedEventArgs e) 
{ 
    // Create the newWindowId and stuff... 

    await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newWindowId, 
     ViewSizePreference.Default, 
     e.CurrentlyShownApplicationViewId, 
     ViewSizePreference.Default); 

मूल रूप से, आप तीसरे पैरामीटरanchorViewId जो

बुला (लंगर) खिड़की की आईडी है निर्दिष्ट करने के लिए की जरूरत है।

इस मामले में, आपको बस e.CurrentlyShownApplicationViewId में पास करने की आवश्यकता है।

संबंधित मुद्दे