2015-11-10 4 views
7

Привет, Хороший день. Я просто новый с дизайном WPF и MVVM, и я многому научился из блогов и видео сэра БРИАНА ЛАГУНАСА в PRISM .. но просто хочу задать вопрос noob .. что-то не так с моим кодом, он работает для меня ... любая помощь очень ценится. вот мой код:Prism 6 DelegateCommand ObservesProperty code

МОЙ ВЗГЛЯД МОДЕЛЬ

public class Person : BindableBase 
{ 
    private myPErson _MyPerson; 
    public myPErson MyPerson 
    { 
     get { return _MyPerson; } 
     set 
     { 
      SetProperty(ref _MyPerson, value); 
     } 
    } 

    public Person() 
    { 
     _MyPerson = new myPErson(); 
     updateCommand = new DelegateCommand(Execute, CanExecute).ObservesProperty(() => MyPerson.FirstName).ObservesProperty(() => MyPerson.Lastname); 

    // updateCommand = new DelegateCommand(Execute).ObservesCanExecute((p) => CanExecute); /// JUST WANNA TRY THIS BUT DUNNO HOW 
    } 

    private bool CanExecute() 
    { 
     return !String.IsNullOrWhiteSpace(MyPerson.FirstName) && !String.IsNullOrWhiteSpace(MyPerson.Lastname); 
    } 

    private void Execute() 
    { 
     MessageBox.Show("HOLA"); 
    } 

    public DelegateCommand updateCommand { get; set; } 
} 

MyModel

Заявленный в другой файл класса

public class myPErson : BindableBase 
{ 
    private string _firstName; 
    public string FirstName 
    { 
     get { return _firstName; } 
     set 
     { 
      SetProperty(ref _firstName, value); 
     } 
    } 

    private string _lastname; 
    public string Lastname 
    { 
     get { return _lastname; } 
     set 
     { 
      SetProperty(ref _lastname, value); 
     } 
    } 
} 

Посмотреть Xa мл Код

<Window x:Class="Prism6Test.Views.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:myVM="clr-namespace:Prism6Test.ViewModel" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <myVM:Person x:Key="mainVM"/> 
    </Window.Resources> 
<Grid DataContext="{StaticResource mainVM}"> 
     <TextBox HorizontalAlignment="Left" Height="23" Margin="217,103,0,0" TextWrapping="Wrap" Text="{Binding MyPerson.FirstName,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/> 
     <TextBox HorizontalAlignment="Left" Height="23" Margin="217,131,0,0" TextWrapping="Wrap" Text="{Binding MyPerson.Lastname,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/> 
     <Button Content="Button" Command="{Binding updateCommand}" HorizontalAlignment="Left" Margin="242,159,0,0" VerticalAlignment="Top" Width="75"/> 

    </Grid> 
</Window> 

Я уже читал это, но он не работает для меня .. и не могу понять, как я могу правильно закодировать это .. пожалуйста, помогите мне ragarding Этот вопрос ..HOPE для любого ответа soon..thx

ObservesProperty method isn't observing model's properties at Prism 6

+0

Что такое кнопка делает? – Jens

+0

Почтовый ящик "HOLA". – Neil

+0

Хорошо. Теперь я вижу это. в чем проблема кода? Вы ничего не видите в текстовых блоках? – Jens

ответ

4

1) вы не можете использовать сложные DataModel, как вы хотите, так что попробуйте

private myPErson _MyPerson; 
    public myPErson MyPerson 
    { 
     get { return _MyPerson; } 
     set 
     { 
      if (_MyPerson != null) 
       _MyPerson.PropertyChanged -= MyPersonOnPropertyChanged; 

      SetProperty(ref _MyPerson, value); 


      if (_MyPerson != null) 
       _MyPerson.PropertyChanged += MyPersonOnPropertyChanged; 
     } 
    } 

    private void MyPersonOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) 
    { 
     updateCommand.RaiseCanExecuteChanged(); 
    } 

2) Измените конструктор

public Person() 
    { 
     MyPerson = new myPErson(); 
     updateCommand = new DelegateCommand(Execute, CanExecute); 
    } 
+0

спасибо .. !!! это работает для меня сейчас sir @galakt .. – Neil

+0

@Neil Отметьте этот ответ как решение, пожалуйста, если это помогло вам – galakt

3

Прежде всего, я должен сказать кое-что о вашем названии. Назовите свои классы понятными. Позвоните по номеру ViewModel, например. PersonViewModel или просто ViewModel, когда ваше приложение не так много, а не Person, потому что Person - это, очевидно, Модель. Более того, myPErson - очень плохое имя, потому что он очень похож на ваш другой класс Person, и вы должны PascalCase ваши имена классов.

Теперь вашему с кодом. Я ничего не знаю о Prism, поэтому мой код зависит от шаблона MVVM только без поддержки библиотек Prism.

Сначала я хочу изменить МодельPerson. Класс выглядит очень просто в моем коде (просто использует авто свойства):

public class Person 
{ 
    public string FirstName { get; set; } 

    public string LastName { get; set; } 

    public Person() 
    { 
     this.LastName = string.Empty; 
     this.FirstName = string.Empty; 
    } 
} 

PersonViewModel является littlebit более сложным, поскольку он реализует интерфейс INotifyPropertyChanged. Я также использую очень распространенный RelayCommand, который вы можете найти в ссылке в соответствии с принятым ответом.

public class PersonViewModel : INotifyPropertyChanged 
{ 
    private Person person; 

    private ICommand updateCommand; 

    public PersonViewModel() 
    { 
     this.Person = new Person(); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public Person Person 
    { 
     get 
     { 
      return this.person; 
     } 

     set 
     { 
      this.person = value; 

      // if you use VS 2015 or/and C# 6 you also could use 
      // this.OnPropertyChanged(nameof(Person)); 
      this.OnPropertyChanged("Person"); 
     } 
    } 

    public ICommand UpdateCommand 
    { 
     get 
     { 
      if (this.updateCommand == null) 
      { 
       this.updateCommand = new RelayCommand<Person>(this.OpenMessageBox, this.OpenMessageBoxCanExe); 
      } 

      return this.updateCommand; 
     } 
    } 

    [NotifyPropertyChangedInvocator] 
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChangedEventHandler handler = this.PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    private void OpenMessageBox(Person person) 
    { 
     MessageBox.Show("Hola"); 
    } 

    private bool OpenMessageBoxCanExe(Person person) 
    { 
     if (person == null) 
     { 
      return false; 
     } 

     if (string.IsNullOrWhiteSpace(person.FirstName) || string.IsNullOrWhiteSpace(person.LastName)) 
     { 
      return false; 
     } 

     return true; 
    } 
} 

Я прояснил ваш взгляд, потому что он намного короче. но в целом все оставалось прежним. я просто переименовал свойства и прочее:

<Window ...> 
    <Window.Resources> 
     <wpfTesst:PersonViewModel x:Key="ViewModel" /> 
    </Window.Resources> 
    <Grid DataContext="{StaticResource ViewModel}"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="Auto"/> 
     </Grid.RowDefinitions> 
     <TextBox Grid.Row="0" TextWrapping="Wrap" Text="{Binding Person.FirstName, UpdateSourceTrigger=PropertyChanged}" /> 
     <TextBox Grid.Row="1" TextWrapping="Wrap" Text="{Binding Person.LastName, UpdateSourceTrigger=PropertyChanged}" /> 
     <Button Grid.Row="2" Content="Button" Command="{Binding UpdateCommand}" CommandParameter="{Binding Person}"/> 
    </Grid> 
</Window> 

В целом я бы рекомендовал вам использовать общий шаблон MVVM без библиотеки Prism.Когда вы поняли, что MVVM хорошо, вы все равно можете пойти на Prism. Надеюсь, это поможет.

+0

поблагодарить вас за предложение sir @Jens Horstmann .. и это поможет мне улучшить мое кодирование ... из любопытства просто хочу использовать библиотеку PRISM и изучить ее. Могу ли я спросить у вас ссылку, книгу для моей справки? для будущего изучения..пожалуйста пожалуйста ... thx очень – Neil

+0

@Neil делать то, что вы хотите, со своими ссылками = P – Jens

+0

haha ​​.. любая предлагаемая ссылка от вас сэр^_^.... для моей будущей справки сэр..i изучающ ... пожалуйста пожалуйста ... @Jens Horstmann – Neil

0

Просмотр Xaml Код

<Window x:Class="Prism6Test.Views.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:myVM="clr-namespace:Prism6Test.ViewModel" 
    Title="MainWindow" Height="350" Width="525"> 

Вы пропускаете ViewModelLocator

xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms" 
    prism:ViewModelLocator.AutowireViewModel="True" 
Смежные вопросы