1

HyXamarin.Forms PCL MVVM Light> Пользовательский контроль> Лучшая практика?

Я хотел бы поделиться своим подходом к пользовательскому управлению xamarin.forms в проекте Xamarin PCL с MVVM-Light. Что вы думаете об этом?

пользовательского элемента управления -> PersonPanel.xaml:

<?xml version="1.0" encoding="utf-8" ?> 
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      x:Class="xxx.PersonPanel"> 
    <StackLayout Orientation="Vertical"> 
    <Label x:Name="titleLabel" Text="{Binding TitleLabel}"/> 
    <Entry x:Name="filterText" Placeholder="{Binding FilterPlaceholderText}" Text="{Binding Filter.Lookup}" TextChanged="OnFilterTextChanged"/> 
    <Label x:Name="resultText" Text="{Binding ResultText}" IsVisible="{Binding ResultTextVisible}"/> 
    </StackLayout> 
</ContentView> 

Code-Behind -> PersonPanel.xaml.cs:

public partial class PersonPanel : ContentView 
{ 
    public PersonPanel() 
    { 
     InitializeComponent(); 

     //Init ViewModel 
     BindingContext = ServiceLocator.Current.GetInstance<PersonPanelViewModel>(); 
    } 

    private PersonPanelViewModel PersonPanelViewModel 
    { 
     get 
     { 
      return (PersonPanelViewModel)BindingContext; 
     } 
    } 

    public string TitleLabel 
    { 
     get 
     { 
      return PersonPanelViewModel.TitleLabel; 
     } 
     set 
     { 
      PersonPanelViewModel.TitleLabel = value; 
     } 
    } 

    public string FilterPlaceholderText 
    { 
     get 
     { 
      return PersonPanelViewModel.FilterPlaceholderText; 
     } 
     set 
     { 
      PersonPanelViewModel.FilterPlaceholderText = value; 
     } 
    } 

    private void OnFilterTextChanged(object sender, EventArgs e) 
    { 
     PersonPanelViewModel.SearchCommand.Execute(null); 
    } 
} 

ViewModel -> PersonPanelViewModel:

public class PersonPanelViewModel : ViewModelBase 
{ 
    private IPersonService _personService; 

    private decimal _personId = 0; 
    private string _titleLabel = string.Empty; 
    private string _filterPlaceholderText = string.Empty; 
    private string _resultText = string.Empty; 
    private bool _resultTextVisible = true; 

    public PersonPanelViewModel(IPersonService personService) 
    { 
     _personService = personService; 

     // Init Filter 
     Filter = new PersonFilter(); 

     // Init Commands 
     SearchCommand = new RelayCommand(Search); 
    } 

    public ICommand SearchCommand { get; set; } 

    public PersonFilter Filter 
    { 
     get; 
     private set; 
    } 

    public string ResultText 
    { 
     get 
     { 
      return _resultText; 
     } 
     set 
     { 
      Set(() => ResultText, ref _resultText, value); 
     } 
    } 

    public bool ResultTextVisible 
    { 
     get 
     { 
      return _resultTextVisible; 
     } 
     set 
     { 
      Set(() => ResultTextVisible, ref _resultTextVisible, value); 
     } 
    } 

    public string FilterPlaceholderText 
    { 
     get 
     { 
      return _filterPlaceholderText; 
     } 
     set 
     { 
      Set(() => FilterPlaceholderText, ref _filterPlaceholderText, value); 
     } 
    } 

    public string TitleLabel 
    { 
     get 
     { 
      return _titleLabel; 
     } 
     set 
     { 
      Set(() => TitleLabel, ref _titleLabel, value); 
     } 
    } 

    public decimal PersonId 
    { 
     get 
     { 
      return _PersonId; 
     } 
     set 
     { 
      Set(() => PersonId, ref _PersonId, value); 
     } 
    } 

    private async void Search() 
    { 
     //Reset 
     ResultText = string.Empty; 
     ResultTextVisible = false; 
     PersonId = 0; 

     if (Filter.PersonLookup != null && Filter.PersonLookup.Length >= 3) 
     { 
      //Call to Person Service 
      List<PersonResult> Person = await _personService.FindpersonByFilter(Filter);    

      if (Person.Count == 1) 
      { 
       PersonId = Person[0].PersonId; 

       ResultText = Person[0].PersonName; 
       ResultTextVisible = true; 
      } 
     } 
    } 
} 

Использование контроля в другом Вид:

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      xmlns:components="clr-namespace:xxx.ViewElements.Components" 
      x:Class="xxx.MainPage"> 
    <StackLayout Orientation="Vertical"> 
    <components:PersonPanel x:Name="personPanel" TitleLabel="Person" FilterPlaceholderText="Type your search criteria here..."/> 
    </StackLayout> 
</ContentPage> 

Я использую Autofac в качестве контейнера IOC.

Что вы думаете об этом? Я использую MVVM правильным способом (это для меня очень ново)?

Есть ли лучший способ справиться с вызовом команды из события (TextChanged) в представлении?

Что о свойствах в Code-Behind (которые выполняют маршрутизацию в ViewModel)?

Edit: Я попытаюсь описать, что я хочу добиться:

  • Создание нашего собственного контроля (многоразовые в различных точек зрения, кросс-платформенные) -> PersonPanel.xaml
  • Написанное в XAML в нашем проекте PCL с контролем чистого Xamarin.Forms в нем
  • управление должно иметь это собственные команды (поиск) и свойство
  • Одна из команд используют службу
  • Контроль должен получить Услугу (в качестве интерфейса) впрыскивается через МОК
  • Сама служба также реализована в проекте PCL и делает REST вызов к Webservice
  • Результат приема вызова, чем набор к свойство управления -> ResultText недвижимости
  • Результат виден пользователя

-> с выше реализации, все это работает, но я не уверен, что это правильный путь ..

Чем ks для вашей помощи!

С наилучшими пожеланиями, Питер

ответ

0

подход для отображения события в команде точно так, как я хотел бы выполнить.

Остальное немного запутывает. Общая схема заключается в создании связанных свойств в вашем элементе управления, которые подвергаются воздействию модели представления при создании экземпляра в представлении хоста.Ниже приведена основная структура выборки:

public class TestLabelControl : Label 
{ 
    public static readonly BindableProperty TestTitleProperty = BindableProperty.Create< TestLabelControl, string> (p => p.TestTitle, null); 

    public string TestTitle { 
     get { 
      return (object)GetValue (TestTitleProperty); 
     } 
     set { 
      SetValue (TestTitleProperty, value); 
     } 
    } 
} 

public class TestContentPage : ContentPage 
{ 
    public TestContentPage() 
    { 
     var testLabel = new TestLabel(); 
     testLabel.SetBinding<TestContentPageViewModel>(TestLabel.TestTitleProperty, vm => vm.TestLabelTitle, BindingMode.Default); 
     Content = testLabel; 
    } 
} 


public class TestContentPageViewModel 
{ 
    public string TestLabelTitle{get;set;} 

    public TestContentPageViewModel() 
    { 
     TestLabelTitle = "Something random"; 
    } 
} 

Затем вы создадите собственные средства визуализации для обработки чертежа на каждой платформе.

Следуя этому подходу, вы сохраняете код разделенным и кратким. Кажется, это немного длинный способ сделать все, но он очень масштабируемый и настраиваемый.

+0

Правильно ли иметь ViewModel для моего компонента, например, для логики поиска? Эта логика устанавливает другое свойство Component-ViewModel (ResultText), как это Значение, отображаемое в представлении? Моя идея - иметь компонент (ContentView) со своим собственным ViewModel для повторного использования. Этот компонент должен использоваться другими элементами управления. Я думаю, что я понимаю связанные свойства в файле Code-Behind, но я не уверен, как они подключены к Component-ViewModel. Нам не нужны встроенные средства визуализации, мы просто используем компоненты xamarin.forms. Спасибо за вашу помощь. –

+0

Если вы хотите создать многоразовый элемент управления, он должен быть как можно более агностиком, поскольку логика была применена моделью просмотра соответствующего вида. Это единственный способ убедиться, что элемент управления не раздувается с условным кодом. Возможно, если вы подробно расскажете о том, чего вы пытаетесь достичь, сообщество предоставит более подробный пример. – JordanMazurke

+0

Я отредактировал свой ответ, надеюсь, это немного прояснит его ... –

Смежные вопросы