我的DataGrid
中有一列是价格字段。
在表单底部的TextBlock
中。
如何根据价格列的值显示TextBlock
中的总价值?
XAML的代码:
<Grid>
<DataGrid HorizontalAlignment="Left" ItemsSource="{Binding Path=SaleryDetailsCollection, Mode=TwoWay}" AutoGenerateColumns="False" VerticalAlignment="Top" Width="640" Height="192" >
<DataGrid.Columns>
<DataGridTextColumn Header="Type" Binding="{Binding Type, Mode=TwoWay, NotifyOnTargetUpdated=True, ValidatesOnDataErrors=True}" Width="*" />
<DataGridTextColumn Header="Amount" Binding="{Binding Price, Mode=TwoWay, NotifyOnTargetUpdated=True, ValidatesOnDataErrors=True}" Width="*" />
</DataGrid.Columns>
</DataGrid>
<TextBlock HorizontalAlignment="Left" Margin="415,358,0,0" TextWrapping="Wrap" Text="{Binding SalaryTotal}" VerticalAlignment="Top"/>
</Grid>
视图模型:
public ObservableCollection<SaleryDetailsModel> SaleryDetailsCollection
{
get { return _SaleryDetailsCollection; }
set
{
SalaryTotal = SaleryDetailsCollection.Sum(x => x.Amount);
_SaleryDetailsCollection = value;
NotifyPropertyChanged("SaleryDetailsCollection");
}
}
public Double SalaryTotal
{
get { return _SalaryTotal; }
set
{
_SalaryTotal = value;
NotifyPropertyChanged("SalaryTotal");
}
}
类SaleryDetailsMode
class SaleryDetailsModel:ViewModel
{
private Double _Amount;
private String _Type;
public Double Amount
{
get { return _Amount; }
set
{
_Amount = value;
NotifyPropertyChanged("Amount");
}
}
public String Type { get { return _Type; } set { _Type = value; NotifyPropertyChanged("Type"); } }
}
Class ViewModel
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
答案 0 :(得分:2)
在构造函数
中添加此代码SaleryDetailsCollection = new ObservableCollection<SaleryDetailsModel>();
SaleryDetailsCollection.CollectionChanged += MyItemsSource_CollectionChanged;
在ViewModel中
void MyItemsSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
foreach (SaleryDetailsModel item in e.NewItems)
item.PropertyChanged += MyType_PropertyChanged;
if (e.OldItems != null)
foreach (SaleryDetailsModel item in e.OldItems)
item.PropertyChanged -= MyType_PropertyChanged;
}
void MyType_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Amount")
DoWork();
}
private void DoWork()
{
SalaryTotal = SaleryDetailsCollection.Sum(x => x.Amount);
}
XAML
<Grid>
<DataGrid HorizontalAlignment="Left" ItemsSource="{Binding Path=SaleryDetailsCollection, Mode=TwoWay}" AutoGenerateColumns="False" VerticalAlignment="Top" Width="640" Height="192" >
<DataGrid.Columns>
<DataGridTextColumn Header="Type" Binding="{Binding Type, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="*" />
<DataGridTextColumn Header="Amount" Binding="{Binding Price, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="*" />
</DataGrid.Columns>
</DataGrid>
<TextBlock HorizontalAlignment="Left" Margin="415,358,0,0" TextWrapping="Wrap" Text="{Binding SalaryTotal}" VerticalAlignment="Top"/>
答案 1 :(得分:0)
必须在字段分配后进行计算:
public ObservableCollection<SaleryDetailsModel> SaleryDetailsCollection
{
get { return _SaleryDetailsCollection; }
set
{
_SaleryDetailsCollection = value;
SalaryTotal = SaleryDetailsCollection.Sum(x => x.Amount); // This line must be after the field assignment.
NotifyPropertyChanged("SaleryDetailsCollection");
}
}
答案 2 :(得分:0)
您需要使用一个集合,该集合会在其属性发生变化时收到通知。请参阅链接https://social.msdn.microsoft.com/Forums/silverlight/en-US/12915e07-be95-4fc5-b8f0-b0a49b10bc57/observablecollection-item-changed。它有NotifyableCollection。我已将它用于以下代码。
<Grid>
<StackPanel>
<DataGrid x:Name="dgr" HorizontalAlignment="Left" ItemsSource="{Binding Path=Salaries, Mode=TwoWay}"
AutoGenerateColumns="True" VerticalAlignment="Top" Width="640" Height="192" >
</DataGrid>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Text="{Binding TotalSalary}">
</TextBlock>
</StackPanel>
</Grid>
class ViewModel : INotifyPropertyChanged
{
private NotifiableCollection<Salary> salaries;
double _totalSal;
public double TotalSalary
{
get { return _totalSal = Salaries.Sum(x => x.Amount); }
set { _totalSal = value; }
}
public NotifiableCollection<Salary> Salaries
{
get { return salaries; }
set
{
salaries = value;
if (salaries != null)
{
salaries.ItemChanged += salaries_ItemChanged;
}
}
}
void salaries_ItemChanged(object sender, NotifyCollectionChangeEventArgs e)
{
OnPropertyChanged("TotalSalary");
}
public ViewModel()
{
Salaries = new NotifiableCollection<Salary>();
for (int i = 0; i < 10; i++)
{
Salary s = new Salary() { Type="Type"+i,Amount=new Random().Next(20000,30000)};
Salaries.Add(s);
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
class Salary : INotifyPropertyChanged
{
private string type;
public string Type
{
get { return type; }
set { type = value; OnPropertyChanged("Type"); }
}
private double amount;
public double Amount
{
get { return amount; }
set { amount = value; OnPropertyChanged("Amount"); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
public class NotifyCollectionChangeEventArgs : PropertyChangedEventArgs
{
public int Index { get; set; }
public NotifyCollectionChangeEventArgs(int index, string propertyName) : base(propertyName) { Index = index; }
}
public class NotifiableCollection<T> : ObservableCollection<T> where T : class, INotifyPropertyChanged
{
public event EventHandler<NotifyCollectionChangeEventArgs> ItemChanged;
protected override void ClearItems()
{
foreach (var item in this.Items)
item.PropertyChanged -= ItemPropertyChanged;
base.ClearItems();
}
protected override void SetItem(int index, T item)
{
this.Items[index].PropertyChanged -= ItemPropertyChanged;
base.SetItem(index, item);
this.Items[index].PropertyChanged += ItemPropertyChanged;
}
protected override void RemoveItem(int index)
{
this.Items[index].PropertyChanged -= ItemPropertyChanged;
base.RemoveItem(index);
}
protected override void InsertItem(int index, T item)
{
base.InsertItem(index, item);
item.PropertyChanged += ItemPropertyChanged;
}
private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
T changedItem = sender as T;
OnItemChanged(this.IndexOf(changedItem), e.PropertyName);
}
private void OnItemChanged(int index, string propertyName)
{
if (ItemChanged != null)
this.ItemChanged(this, new NotifyCollectionChangeEventArgs(index, propertyName));
}
}