Prism 6 DelegateCommand ObservesProperty代码

时间:2015-11-10 06:33:30

标签: c# wpf mvvm prism

嗨,美好的一天,我是WPF和MVVM设计模式的新手,我从PRISM的BRIAN LAGUNAS先生的博客和视频中学到了很多东西......但只是想问一个菜鸟问题。 .whats错误的我的代码它为我工作...任何帮助非常感谢谢谢。 这是我的代码:

我的观看模式

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

查看 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">
    <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>

我已经读过这个但它对我不起作用..并且无法理解我怎样才能正确编码...请帮我理解这件事..希望对于任何回复很快..thx

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

3 个答案:

答案 0 :(得分:4)

1)你不能像你想的那样使用复杂的数据模型,所以试试吧

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

答案 1 :(得分:3)

首先我要谈谈你的命名。为您的课程命名清楚。调用您的 ViewModel ,例如当您的应用程序不是那么大而不是PersonViewModel时,ViewModel或仅Person,因为Person显然是模型。此外,myPErson是一个非常糟糕的名称,因为它与您的其他Person类非常相似,您应该PascalCase您的类名。

现在代码。我对Prism一无所知,所以我的代码只有在没有Prism Libraries支持的情况下依赖于MVVM模式。

首先,我要更改模型 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有点复杂,因为它实现了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>

总而言之,我建议你使用没有Prism Library的常见MVVM模式。当你理解MVVM的优点时,你仍然可以选择Prism。 希望它有所帮助。

答案 2 :(得分: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"