Search code examples
mvvmcross

Custom view presenter in WPF application


I am writing a WPF application with MvvmCross. I want to have a custom view presenter. Here is what I wrote:

public class ViewPresenter : MvxWpfViewPresenter
{
    ContentControl _contentControl;

    FrameworkElement _currentContentView;
    FrameworkElement _rootContentView;

    public ViewPresenter(ContentControl c)
    {
        _contentControl = c;

        AddPresentationHintHandler<SetRootHint>(SetRootHintHandler);
        AddPresentationHintHandler<PopToRootHint>(PopToRootHintHandler);
    }

    protected override void ShowContentView(FrameworkElement element, MvxContentPresentationAttribute attribute, MvxViewModelRequest request)
    {
        base.ShowContentView(element, attribute, request);

        _currentContentView = element;
    }

    private bool SetRootHintHandler(SetRootHint hint)
    {
        _rootContentView = _currentContentView;

        return true;
    }

    private bool PopToRootHintHandler(PopToRootHint hint)
    {

        return true;
    }
}

I am registering it in my Setup class:

public class Setup : MvxWpfSetup<Core.App>
{
    protected override IMvxWpfViewPresenter CreateViewPresenter(ContentControl root)
    {
        return new ViewPresenter(root);
    }
}

As soon as I try to show my first view, it crashes on this line:

base.ShowContentView(element, attribute, request);

With the message:

System.InvalidOperationException: 'Sequence contains no elements'

If I don't overried ShowContentView, it still crashes. And if I don't call base.ShowContentView(element, attribute, request) it doesn't display my view.

EDIT

After enabling Common Language Runtime Exceptions in my Visual Studio environment, I can see the exception is actually coming from mscorlib.dll and is asking for AsyncMethodBuilder.cs to view the source for the call stack frame when the exception is thrown. All my nuget packages are up to date, and am running on Windows 10. I believe WPF has been deprecated as of Windows 10. My WPF project is targeting .NET 4.7.2 and my Core project is targeting .NET Standard 2.0. But I still don't know how to fix this.. I'm using the latest MvvmCross too (6.1.2.0).

EDIT 2

I made a small sample application with the same issue here:

https://drive.google.com/file/d/1uROc8TYzWdx54BV8LtgCNLtwhc_MhXq3/view?usp=sharing


Solution

  • Thanks for the sample. I was able to figure it out.

    You're experiencing this issues becuase you're not calling the base constructor on the ViewPresenter. Change your ViewPresenter code to this:

    public ViewPresenter(ContentControl c) : base(c)
    {
        _contentControl = c;
    
        AddPresentationHintHandler<SetRootHint>(SetRootHintHandler);
        AddPresentationHintHandler<PopToRootHint>(PopToRootHintHandler);
    }
    

    That way, the base constructor will be called and the ContentControl will be added to _frameworkElementsDictionary, which in turn will not throw an exception

    Sequence contains no elements

    'cause there will be one element in it