I have a Xamarin project that uses a fairly standard MVVM pattern. The following code shows the structure of this and all compiles and runs as expected:
public abstract class ViewLogicBase
{
public abstract void DisplayLogicType();
}
public class FirstViewLogic : ViewLogicBase
{
public override void DisplayLogicType() { Debug.WriteLine( "FirstViewLogic" );
}
public string BindablePropertyInFirstViewLogic => "BindablePropertyInFirstViewLogic";
}
public class SecondViewLogic : ViewLogicBase
{
public override void DisplayLogicType() { Debug.WriteLine( "SecondViewLogic" ); }
public string BindablePropertyInSecondViewLogic => "BindablePropertyInSecondViewLogic";
}
public abstract class ViewBase
{
public ViewBase( ViewLogicBase viewLogicBase ) => BindingContext = viewLogicBase;
public abstract void DisplayViewType();
public ViewLogicBase BindingContext { get; }
}
public class FirstView : ViewBase
{
public FirstView( ViewLogicBase viewLogicBase ) : base( viewLogicBase ) {}
public override void DisplayViewType() { Debug.WriteLine( "FirstView" ); }
public void FirstMiscellaneousFunction()
{
DisplayViewType();
BindingContext.DisplayLogicType();
}
}
public class SecondView : ViewBase
{
public SecondView( ViewLogicBase viewLogicBase ) : base( viewLogicBase ) {}
public override void DisplayViewType() { Debug.WriteLine( "SecondView" ); }
public void SecondMiscellaneousFunction()
{
DisplayViewType();
BindingContext.DisplayLogicType();
Debug.WriteLine( $"Specific function in SecondViewLogic returned: {((SecondViewLogic)BindingContext).BindablePropertyInSecondViewLogic}" );
}
}
class Program
{
static void Main( string[] args )
{
FirstView firstView = new FirstView( new FirstViewLogic() );
SecondView secondView = new SecondView( new SecondViewLogic() );
firstView.FirstMiscellaneousFunction();
secondView.SecondMiscellaneousFunction();
Console.ReadLine();
}
}
When I want to bind to a property in the view-model in C# code, I would like to use
nameof()
instead of a magic string. The problem is that
nameof()
will not accept a sub-expression. This is illustrated by the commented-out line in
SecondMiscellaneousFunction()
above.
What is the best way round this?
What I have tried:
I have thought about adding a generic type parameter to the
ViewBase
...
public abstract class ViewBase<T> where T : ViewLogicBase
...but this does not play well with the navigation code I have inherited, nor does it work with XAML.
The only other solution I can think of is the cheap-and-cheerful adding of a specific property in each view that performs the cast...
public FirstViewLogic TypedBindingContext => (FirstViewLogic)BindingContext;
But this seems a bit rough round the edges.