gpt4 book ai didi

c# - ObservesProperty 方法不在 Prism 6 上观察模型的属性

转载 作者:太空狗 更新时间:2023-10-30 00:50:10 25 4
gpt4 key购买 nike

我正在尝试学习 Prism MVVM,我正在制作一个包含 2 个字段和一个按钮的窗口,当这两个字段不为空时该按钮将启用。

问题是我找不到使方法 ObservesProperty() 对对象(在那种情况下为 Pessoa)起作用的方法。 CanExecuteAtualizar() 方法仅在应用程序启动时被调用,当我编辑文本字段 NomeSobrenome 时,按钮和方法未被触发...

我尝试在没有模型的情况下工作,将 NomeSobrenomeUltimaAtualizacao 属性直接放在 ViewModel 中,它工作正常,禁用根据方法 CanExecuteAtualizar 返回的按钮,但我想将它与模型一起使用。有办法做到这一点吗?

ViewAViewModel.cs

public class ViewAViewModel : BindableBase
{
private Pessoa _pessoa;

public Pessoa Pessoa
{
get { return _pessoa; }
set { SetProperty(ref _pessoa, value); }
}

public ICommand CommandAtualizar { get; set; }

public ViewAViewModel()
{
Pessoa = new Pessoa();
Pessoa.Nome = "Gabriel";
CommandAtualizar = new DelegateCommand(ExecuteAtualizar, CanExecuteAtualizar).ObservesProperty(() => Pessoa.Nome).ObservesProperty(() => Pessoa.Sobrenome);
}

public bool CanExecuteAtualizar()
{
return !string.IsNullOrWhiteSpace(Pessoa.Nome) && !string.IsNullOrWhiteSpace(Pessoa.Sobrenome);
}

public void ExecuteAtualizar()
{
Pessoa.UltimaAtualizacao = DateTime.Now;
}
}

Pessoa.cs

public class Pessoa : BindableBase
{
private string _nome;

public string Nome
{
get { return _nome; }
set { SetProperty(ref _nome, value); }
}

private string _sobrenome;

public string Sobrenome
{
get { return _sobrenome; }
set { SetProperty(ref _sobrenome, value); }
}

private DateTime? _ultimaAtualizacao;

public DateTime? UltimaAtualizacao
{
get { return _ultimaAtualizacao; }
set { SetProperty(ref _ultimaAtualizacao, value); }
}
}

ViewA.xaml

<UserControl x:Class="PrismDemo.Views.ViewA"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PrismDemo.Views"
mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="500">
<Grid Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<Label Content="Nome:" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
<TextBox Grid.Column="1" Grid.Row="0" Margin="3" TabIndex="0" Text="{Binding Pessoa.Nome, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="Sobrenome:" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center" />
<TextBox Grid.Column="1" Grid.Row="1" Margin="3" TabIndex="1" Text="{Binding Pessoa.Sobrenome, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="Última atualização:" Grid.Column="0" Grid.Row="2" HorizontalAlignment="Left" VerticalAlignment="Center" />
<Label Grid.Column="1" Grid.Row="2" Margin="3" HorizontalAlignment="Left" Content="{Binding Pessoa.UltimaAtualizacao, Mode=TwoWay}" />
<Button Content="Atualizar" Grid.Column="1" Grid.Row="3" Width="70" Margin="2,2,3,2" HorizontalAlignment="Right" Command="{Binding CommandAtualizar}" />
</Grid>
</UserControl>

最佳答案

DelegateCommand.ObservesPropery 不支持复杂的对象属性。它只支持命令中定义的 ViewModel 上存在的属性。这是因为复杂对象的生命周期是未知的,如果创建了很多对象实例就会造成内存泄漏。我的建议是像这样定义您的属性:

private Pessoa _pessoa;
public Pessoa Pessoa
{
get { return _pessoa; }
set
{
if (_pessoa != null)
_pessoa.PropertyChanged -= PropertyChanged;

SetProperty(ref _pessoa, value);


if (_pessoa != null)
_pessoa.PropertyChanged += PropertyChanged;
}
}

然后在PropertyChanged方法中,调用DelegateCommand.RaiseCanExecuteChanged

编辑:Prism for Xamarin.Forms 7.0 现已提供复杂属性支持。

关于c# - ObservesProperty 方法不在 Prism 6 上观察模型的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33313190/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com