如何将Checkbox更改为Datagrid来实现功能?

时间:2018-07-10 17:54:40

标签: c# wpf mvvm

我对WPF有要求,我有一个ViewModel,它具有一个名为 TotalImport 的长属性,以及一个名为 CuentasxCobrar 的ObservableCollection。 CxC是一类,具有一个名为 Import 的长属性和一个名为 Selected 的bool属性。 CuentasxCobrar是我视图中一个Datagrid的ItemSource 我必须为每个元素的 Import 之和计算 TotalImport ,其中 true Selected 我的ViewModel可以正常工作,但是永远不会调用计算TotalImport的函数

#region CuentasxCobrar
private ObservableCollection<CxC> _cuentasxcobrar;
public ObservableCollection<CxC> CuentasxCobrar
{
    set
    {
        _cuentasxcobrar = value;
        **ActualizaImporteAcumulado();**
        OnPropertyChanged("CuentasxCobrar");
        OnPropertyChanged("ImporteAcumulado");
    }
    get { return _cuentasxcobrar; }
}
#endregion

    #region ActualizaImporteAcumulado
    private void ActualizaImporteAcumulado()
    {
        _importeacumulado = 0;
        foreach (var item in _cuentasxcobrar)
        {
            _importeacumulado += item.seleccionada ? item.importepago : 0;
        }
        OnPropertyChanged("ImporteAcumulado");
    }
    #endregion

但是,当我在Datagrid中单击复选框时,该复选框绑定到了Selected属性,则不会调用对Cuentas x Cobrar的更改

调查发现:

How to rewrite this DataGrid MouseLeftButtonUp binding to MVVM?

但是永远不会被称为MouseLeftButtonUpCommand函数

我在ViewModer中做了这个:

    #region MouseLeftButtonCommand
    private RelayCommand _mouseLeftButtonUpCommand;
    public RelayCommand MouseLeftButtonUpCommand
    {
        get
        {
            return _mouseLeftButtonUpCommand
                ?? (_mouseLeftButtonUpCommand = new RelayCommand(
                () =>
                {
                    ActualizaImporteAcumulado(); // the handler goes here 
                }));
        }
    }

    public class RelayCommand : ICommand
    {
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
        private Action methodToExecute;
        private Func<bool> canExecuteEvaluator;
        public RelayCommand(Action methodToExecute, Func<bool> canExecuteEvaluator)
        {
            this.methodToExecute = methodToExecute;
            this.canExecuteEvaluator = canExecuteEvaluator;
        }
        public RelayCommand(Action methodToExecute)
            : this(methodToExecute, null)
        {
        }
        public bool CanExecute(object parameter)
        {
            if (this.canExecuteEvaluator == null)
            {
                return true;
            }
            else
            {
                bool result = this.canExecuteEvaluator.Invoke();
                return result;
            }
        }
        public void Execute(object parameter)
        {
            this.methodToExecute.Invoke();
        }
    }
    #endregion

在我看来:

    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
                ........
                    </DataGrid>
                        .....
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="MouseLeftButtonDown" >
                                <i:InvokeCommandAction Command="{Binding MouseLeftButtonUpCommand}" />
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </DataGrid>

怎么了?

1 个答案:

答案 0 :(得分:0)

只要CxC属性设置为新值,INotifyPropertyChanged类应实现PropertyChanged接口并引发Selected事件。

然后,您可以为视图模型中的每个PropertyChanged对象订阅CxC事件,并在它们中的任何一个引发事件时调用ActualizaImporteAcumulado()方法,例如:

private ObservableCollection<CxC> _cuentasxcobrar;
public ObservableCollection<CxC> CuentasxCobrar
{
    set
    {
        if (_cuentasxcobrar != null)
            foreach (var item in _cuentasxcobrar)
                item.PropertyChanged -= Item_PropertyChanged;

        _cuentasxcobrar = value;
        ActualizaImporteAcumulado();
        OnPropertyChanged("CuentasxCobrar");
        OnPropertyChanged("ImporteAcumulado");

        if (_cuentasxcobrar != null)
            foreach (var item in _cuentasxcobrar)
                item.PropertyChanged += Item_PropertyChanged;
    }
    get { return _cuentasxcobrar; }
}

private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "Selected")
        ActualizaImporteAcumulado();
}