简体   繁体   中英

WPF MVVM selected checkbox updated label

I am trying to calculate value all of the selected items in my grid and display the total in a label. But I am not sure how to bind selected values to the label.

<DataGrid ItemsSource="{Binding ReceiptCollection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                                                            
                            ScrollViewer.HorizontalScrollBarVisibility="Auto" Margin="5" ColumnWidth="*">
                              
                <DataGrid.Columns>                       

                    <DataGridTemplateColumn Header="Select" Width="50">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>                        
                    
                    <DataGridTextColumn Header="QTY" Binding="{Binding Quantity}" Width="50" />
                    <DataGridTextColumn Header="Unit Cost" Binding="{Binding UnitPrice}" Width="100" />
                    <DataGridTextColumn Header="Line Value" Binding="{Binding LineValue}" Width="100*" />
                    
                </DataGrid.Columns>
            </DataGrid>
            
<Label Grid.Row="1" Content="SHOW TOTAL LINE VALUE OF SELECTED LINES HERE!"></Label>

How can I show total live value of selected lines only in this Label?
I am using observable collection to bind data in the data grid.

ObservableModelBase: INotifyPropertyChanged, IValidatableObject

public class ReceiptModel : ObservableModelBase<Receipt>
{
    public ReceiptModel(Receipt receipt)
        : base(receipt)
    {
    }       

    public bool IsSelected { get; set; }       
    
    public int Quantity => GetValue<int>();
    public decimal UnitPrice => GetValue<decimal>();       

    public decimal LineValue => Quantity * UnitPrice;
}

public class ReceiptCollection : ObservableCollection<ReceiptModel>
{
    public ReceiptCollection(IEnumerable<Receipt> receipts)
    {
        foreach (var receipt in receipts)
        {
            Add(new ReceiptModel(receipt));
        }
    }
}


public ReceiptViewModel : INotifyPropertyChanged
{
    public ReceiptCollectionn ReceiptCollectionList
    {
        get => _receiptCollectionList;
        set
        {
            _receiptCollectionList = value;
            OnPropertyChanged();
        }
    }
}

There is no direct way to calculate the sum of selected items through binding.

But, more importantly this is not MVVM. You don't bind Model to View. So first you need to separate these two layers and implement some sort of "notify" functionality in your VM. (or maybe you already have that in ObservableModelBase )

Then you can add an event to ReceiptModel (or more precisely ReceiptVM ) and fire it through the callback of IsSelected which then will be attached to and listened by ReceiptCollection . Then ReceiptCollection will update your target property.

 bool _isSelected;
 public bool IsSelected 
 {
     get => _isSelected;
     set
     {
         FireTheEvent(); <--- ReceiptCollectionn  will catch it
         _isSelected = value;
         OnPropertyChanged("IsSelected");
     }
 }

You can also forget about all that (since your code is not MVVM) and just use SelectionChanged event (which is also not MVVM):

    private void MySelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        MySelectedLinesCount += e.AddedItems.Count - e.RemovedItems.Count;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM