What is the right time to register a listener for Share / Search chats?

I need to register a different chat listener for each page. I have 2 pages. I added the following code in each of them:

        DataTransferManager.GetForCurrentView().DataRequested += App_DataRequested;

I added it to the constructor of one page and to the UserControl_Loaded event of the other (on the first page there is simply no UserControl_Loaded, so I added it directly to the constructor). At the moment when the second page is trying to load, I got an exception:

WinRT information: An event handler has already been registered
Additional information: A method was called at an unexpected time.

Where should I place it and what is the “right” time for this? It also looks strange that we have different DataTransferManager for each view, but only one is currently active. Even more, I noticed that if you add only one listener for the first page, other pages will be shared by this listener anyway. If I have only one common listener for all pages, is it correct to register it in app.xaml.cs?

+3
source share
4 answers

How I solved this problem was to unregister the event in the onNavigatedfrom event, as shown below:

protected override void OnNavigatedFrom (NavigationEventArgs e)    {         DataTransferManager.GetForCurrentView(). DataRequested - = App_DataRequested;         base.OnNavigatedFrom();   }

+2

BasePage.cs

public BasePage()
{        
    if (!_isListenToDataRequested)
    {
        _isListenToDataRequested = true;

        DataTransferManager manager = DataTransferManager.GetForCurrentView();  
        manager.DataRequested += AppDataRequested;
    }
}

private async void AppDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
    IShareable shareable = Frame.Content as IShareable;
    if (shareable != null)
    {
        DataRequestDeferral deferral = args.Request.GetDeferral();

        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => shareable.AppDataRequested(sender, args));

        deferral.Complete();
    }
}  

public sealed partial class ContentPage : IShareable
{
    public void AppDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
    {...}
}
+1

Another decision was made as below

private DataTransferManager dataTransferManager;

Put this in a page loading event

 this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, new DispatchedHandler(() =>
            {
                this.dataTransferManager = DataTransferManager.GetForCurrentView();
                this.dataTransferManager.DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(this.OnDataRequested);
            }));

AND

protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        // Unregister the current page as a share source.
        this.dataTransferManager.DataRequested -=
            new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>
                (this.OnDataRequested);
    }
0
source

I suggest doing this in navigation events, the OnNavigatingFrom event will be fired before OnNavigatingTo on the page you are going to so that you do not have this problem.

protected override Task OnNavigatingTo(WinRTXamlToolkit.Controls.AlternativeNavigationEventArgs e)
{
    DataTransferManager.GetForCurrentView().DataRequested += dataTransfer_DataRequested;
    return base.OnNavigatingTo(e);
}

protected override Task OnNavigatingFrom(WinRTXamlToolkit.Controls.AlternativeNavigatingCancelEventArgs e)
{
    DataTransferManager.GetForCurrentView().DataRequested -= dataTransfer_DataRequested;
    return base.OnNavigatingFrom(e);
}

//Note: This is the WinRT Xaml Toolkit version of the events, but the standard events will work the same way.
0
source

All Articles