【问题标题】:How I can implement a function depending Checkbox changes into Datagrid?如何实现取决于复选框更改为 Datagrid 的功能?
【发布时间】:2018-07-10 17:54:39
【问题描述】:

我在 WPF 中有一个要求,我有一个 ViewModel,它有一个名为 TotalImport 的长属性和一个名为 CuentasxCobrar 的 ObservableCollection CxC 是一个类,它有一个名为 Import 的长属性和一个名为 Selected 的 bool 属性 CuentasxCobrar 是我视图中的 Datagrid 的 ItemSource 我必须将 TotalImport 计算为 trueSelected 的每个元素的 Import 总和 我的 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>

怎么了?

【问题讨论】:

  • 您正在将点击处理程序添加到 DataGrid 本身,它被 DataGrid 填充的任何内容(复选框?)拦截,从而防止在 GUI 层次结构中进一步冒泡。在大多数情况下,您不想使用这样的原始点击事件...我必须查看您的整体代码,但您的 DataGrid 复选框绑定到的视图模型应该具有“IsSelected”属性或其他内容应该反过来宣传对 ActualizaImporteAcumulado 的呼吁。
  • 嗨,如果我理解正确的话。你试图用一堆可检查的对象填充一个可观察的列表,作为检查的回报做某种计算?在这种情况下,@MarkFeldman 是对的。您需要使用具有“IsChecked”属性的可检查对象填充可观察列表。在发生 IsChecked 事件时,该对象还需要一个与您的模型挂钩的事件。这是在检查对象时触发您的计算。如果是这种情况,我有一个解决方案,但你需要向我提供你的“CxC”对象类来制定答案。
  • 我在西班牙语论坛的帮助下解决了这个问题:es.stackoverflow.com/questions/179347/…

标签: c# wpf mvvm


【解决方案1】:

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

然后,您可以为视图模型中的每个 CxC 对象订阅 PropertyChanged 事件,并在其中任何一个引发事件时调用 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();
}

【讨论】:

    猜你喜欢
    • 2020-04-07
    • 1970-01-01
    • 2015-05-05
    • 1970-01-01
    • 1970-01-01
    • 2020-12-13
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    相关资源
    最近更新 更多