例如,我一直试图使用MVVMLight的“事件到命令”功能将ViewModel中的命令链接到诸如TextBox中的TextChanged之类的事件。在UWP中,事件到命令会自动假定命令参数是TextChanged的事件args。我不需要,我想发送一个模型作为命令参数,像这样:
<ListView ItemsSource="{Binding ListaAgendaReceita}" Background="DimGray" SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Valor, Mode=TwoWay, Converter={StaticResource CVTStringTODecimal}, UpdateSourceTrigger=PropertyChanged}" Background="LightGray">
<interact:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="TextChanged">
<core:InvokeCommandAction Command="{Binding ElementName=usr_Receita, Path=DataContext.ModificacaoAgendaReceita}"
CommandParameter="{Binding}"/>
</core:EventTriggerBehavior>
</interact:Interaction.Behaviors>
</TextBox>
</DataTemplate>
</ListView.ItemTemplate>
<ListView/>
编辑:该文本框是ListView内DataTemplate的一部分。我已经编辑了代码块以更清楚地反映这一点。我还提供了相同的示例,但CalendarDatePicker却总是失败,无法将模型作为命令参数发送,而是发送了eventargs。
<ListView ItemsSource="{Binding ListaAgendaReceita}" Background="DimGray" SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<CalendarDatePicker BorderThickness="0,3,0,1" DateFormat="{}{day.integer}/{month.integer}/{year.full}"
Date="{Binding Data, Mode=TwoWay, Converter={StaticResource CVTDateTimeTODateTimeOffsetTwoWay}}"
BorderBrush="Green" Background="DarkGray">
<interact:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="DateChanged">
<core:InvokeCommandAction Command="{Binding ElementName=usr_Receita, Path=DataContext.ModificacaoAgendaReceita}"
CommandParameter="{Binding}"/>
</core:EventTriggerBehavior>
</interact:Interaction.Behaviors>
</CalendarDatePicker>
</DataTemplate>
</ListView.ItemTemplate>
<ListView/>
CVTDateTimeTODateTimeOffsetTwoWay是一个简单的Converter,它处理DateProperty,从DateTime转换为DateTimeOffset,反之亦然。
public class CVTDateTimeTODateTimeOffsetTwoWay : IValueConverter
{
public object Convert(object value, Type TargetType, object parameter, string culture)
{
var Data = (DateTime)value;
DateTime date = new DateTime(Data.Year, Data.Month, Data.Day, Data.Hour, Data.Minute, 0);
return new DateTimeOffset(date);
}
public object ConvertBack(object value, Type TargetType, object parameter, string culture)
{
if (value != null)
{
DateTimeOffset dto = (DateTimeOffset)value;
return new DateTime(dto.DateTime.Year, dto.DateTime.Month, dto.DateTime.Day, dto.DateTime.Hour, dto.DateTime.Minute, 0);
}
else return new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 0, 0, 0);
}
}
由于TextBox位于ListView内,因此CommandParameter="{Binding}"
应该是ModelAgendaReceita
,该模型是提供给ListView的ItemsSource的模型。发送给Command的事件不断传递TextChangedEventArgs作为CommandParameter,我想要模型。
编辑。:这是模型的摘要:
public class ModelAgendaReceita : INotifyPropertyChanged
{
public ModelAgendaReceita()
{
}
//Here I create the model based on another model
public ModelAgendaReceita(ModelAgendaReceita p_agendareceita)
{
ID = p_agendareceita.ID;
IDFormaReceita = p_agendareceita.IDFormaReceita;
Data = p_agendareceita.Data;
Valor = p_agendareceita.Valor;
Parcela = p_agendareceita.Parcela;
Recibo = p_agendareceita.Recibo;
Pago = p_agendareceita.Pago;
DataPagamento = p_agendareceita.DataPagamento;
Ativo = p_agendareceita.Ativo;
}
public int ID { get; set; }
public int IDFormaReceita { get; set; }
private DateTime m_data = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 0, 0, 0);
public DateTime Data
{
get { return m_data; }
set { m_data = value; OnPropertyChanged("Data"); }
}
private decimal m_valor;
public decimal Valor
{
get { return m_valor; }
set { m_valor = value; OnPropertyChanged("Valor"); }
}
private int m_parcela;
public int Parcela
{
get { return m_parcela; }
set { m_parcela = value; OnPropertyChanged("Parcela"); }
}
private string m_recibo = string.Empty;
public string Recibo
{
get { return m_recibo; }
set { m_recibo = value; OnPropertyChanged("Recibo"); }
}
private bool m_pago = false;
public bool Pago
{
get { return m_pago; }
set { m_pago = value; OnPropertyChanged("Pago"); }
}
private DateTime m_datapagamento = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 0, 0, 0);
public DateTime DataPagamento
{
get { return m_datapagamento; }
set { m_datapagamento = value; OnPropertyChanged("DataPagamento"); }
}
private bool m_ativo = true;
public bool Ativo
{
get { return m_ativo; }
set { m_ativo = value; OnPropertyChanged("Ativo"); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var changed = PropertyChanged;
if (changed != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
这是我在其中声明ViewModel和Command的方式:
public class HomeVM
{
public DelegateCommand SelecaoSolicitacao { get; set; }
public HomeVM()
{
SelecaoSolicitacao = new DelegateCommand(SelecionarSolicitacao);
}
public void ModificarAgendaReceita(object obj)
{
var p_atual = (ModelAgendaReceita)obj;
var p_inicial = ListaAgendaReceitaInicial.FirstOrDefault(l => l.ID == p_atual.ID);
if (p_inicial != null) p_atual.Status = ModelAgendaReceita.ValidarAlteracao(p_inicial, p_atual);
}
}
这是我用来创建命令的类:
public class DelegateCommand : ICommand
{
//These delegates store methods to be called that contains the body of the Execute and CanExecue methods
//for each particular instance of DelegateCommand.
private readonly Predicate<object> _canExecute;
private readonly Action<object> _Execute;
//Two Constructors, for convenience and clean code - often you won't need CanExecute
public DelegateCommand(Action<object> execute, Predicate<object> canExecute)
{
_canExecute = canExecute;
_Execute = execute;
}
public DelegateCommand(Action<object> execute)
: this(execute, null)
{ }
//CanExecute and Execute come from ICommand
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public void Execute(object parameter)
{
if (!CanExecute(parameter))
return;
_Execute(parameter);
}
/// <summary>
/// Not a part of ICommand, but commonly added so you can trigger a manual refresh on the result of CanExecute.
/// </summary>
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
我从https://onewindowsdev.com/2016/06/16/the-command-pattern-and-mvvm/开始关注。
有人知道该如何解决吗?任何建议/帮助将不胜感激!