Patrick Skelton Ответов: 1

Каков наилучший способ получить строго типизированную ссылку на модель представления в представлении?


У меня есть проект Xamarin, который использует довольно стандартный шаблон MVVM. Следующий код показывает структуру этого и все компилируется и запускается как ожидалось:

   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}" );

           // NOTE: Uncommenting this does not compile.
           //string nameofPropertySpecificToSecondViewLogic = nameof(((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();
       }
   }


Когда я хочу привязаться к свойству в модели представления в коде C#, я хотел бы использовать nameof() вместо волшебной струны. Проблема в том, что nameof() не будет принимать суб-выражение. Это иллюстрируется закомментированной строкой в SecondMiscellaneousFunction() выше.

Каков наилучший способ обойти это?

Что я уже пробовал:

Я уже думал о том, чтобы добавить параметр универсального типа в ViewBase...

public abstract class ViewBase<T> where T : ViewLogicBase


..но это не очень хорошо работает с навигационным кодом, который я унаследовал, и не работает с XAML.

Единственное другое решение, которое я могу придумать,-это дешевое и веселое добавление определенного свойства в каждый вид, который выполняет приведение...

public FirstViewLogic TypedBindingContext => (FirstViewLogic)BindingContext;


Но это кажется немного грубым по краям.

1 Ответов

Рейтинг:
5

Richard Deeming

Вам не нужно передавать экземпляр в nameof - ты можешь просто сделать это:

string nameofPropertySpecificToSecondViewLogic = nameof(SecondViewLogic.BindablePropertyInSecondViewLogic);


Patrick Skelton

Я возьму свое пальто. :-|

(Спасибо!)