C# 可观察集合将列和作为行添加的WPF
我正在处理项目。我使用datagrid填充空的“可观察集合”,它按预期工作。主要问题是,当我在datagrid视图中输入时,我想计算“产品”的“总价”。因为“价格SRC”绑定到需要显示“总价”的文本框中.现在我如何完成这项任务。将不胜感激 这是我的产品类C# 可观察集合将列和作为行添加的WPF,c#,wpf,data-binding,datagrid,observablecollection,C#,Wpf,Data Binding,Datagrid,Observablecollection,我正在处理项目。我使用datagrid填充空的“可观察集合”,它按预期工作。主要问题是,当我在datagrid视图中输入时,我想计算“产品”的“总价”。因为“价格SRC”绑定到需要显示“总价”的文本框中.现在我如何完成这项任务。将不胜感激 这是我的产品类 public class product_data { private String _Name; private String _Brand; private String _Price; public strin
public class product_data
{
private String _Name;
private String _Brand;
private String _Price;
public string Name
{
get { return _Name; }
set { _Name = value; }
}
public string Brand
{
get { return _Brand; }
set { _Brand = value; }
}
public string Price
{
get { return _Price; }
set
{
_Price = value;
}
}
}
这是我的ViewModel类
public class ViewModel:INotifyPropertyChanged
{
public int Pricesrc
{
set;get;
}
public ObservableCollection<product_data> listsrc;
public ObservableCollection<product_data> product_data
{
get { return listsrc; }
set
{
listsrc = value;
}
}
public ViewModel()
{
listsrc = new ObservableCollection<Pages.Product.product_data>();
}
public event PropertyChangedEventHandler PropertyChanged;
public void onPropertyChanged(string prop)
{
PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(prop));
}
}
公共类视图模型:INotifyPropertyChanged
{
公共int价格
{
设置;获取;
}
公共可观测收集清单;
公共可观测收集产品_数据
{
获取{return listsrc;}
设置
{
listsrc=值;
}
}
公共视图模型()
{
listsrc=新的ObservableCollection();
}
公共事件属性更改事件处理程序属性更改;
公共无效onPropertyChanged(字符串属性)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(prop));
}
}
这是我的XAML:
<Grid Background="#C82C2C2C">
<StackPanel Orientation="Vertical" Background="LightGray" Margin="150,60,150,60">
<StackPanel.Effect>
<DropShadowEffect BlurRadius="44"/>
</StackPanel.Effect>
<StackPanel Background="#FF886AF0" Height="80">
<TextBlock Text="Bill" FontSize="25" FontWeight="SemiBold" HorizontalAlignment="Center" Margin="0,20,0,0" Foreground="#FFE6E6E6"></TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,35,0,0">
<TextBox x:Name="txt_Total" ToolTip="Total" Text="{Binding Pricesrc}" Height="50" Background="White" Foreground="#FFB6B2B2" BorderBrush="{x:Null}" BorderThickness="3" HorizontalAlignment="Center" Width="630" FontWeight="DemiBold" FontSize="16" VerticalContentAlignment="Center" Style="{DynamicResource flat_ui_textbox}" GotFocus="textboxes_gotFocus" LostFocus="textboxes_lostFocus"/>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" >
<TextBox x:Name="txt_advance" ToolTip="Advance" Text="Advance" Height="50" Background="White" Foreground="#FFB6B2B2" BorderBrush="{x:Null}" BorderThickness="3" HorizontalAlignment="Center" Width="315" FontWeight="DemiBold" FontSize="16" VerticalContentAlignment="Center" Style="{DynamicResource flat_ui_textbox}" GotFocus="textboxes_gotFocus" LostFocus="textboxes_lostFocus"/>
<TextBox x:Name="txt_pending" ToolTip="Pending" Text="Pending" Height="50" Background="White" Foreground="#FFB6B2B2" BorderBrush="{x:Null}" BorderThickness="3" HorizontalAlignment="Center" Width="315" FontWeight="DemiBold" FontSize="16" VerticalContentAlignment="Center" Style="{DynamicResource flat_ui_textbox}" GotFocus="textboxes_gotFocus" LostFocus="textboxes_lostFocus"/>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" >
<TextBox x:Name="txt_date" ToolTip="Date" Text="Date" Height="50" Background="White" Foreground="#FFB6B2B2" BorderBrush="{x:Null}" BorderThickness="3" HorizontalAlignment="Center" Width="475" FontWeight="DemiBold" FontSize="16" VerticalContentAlignment="Center" Style="{DynamicResource flat_ui_textbox}" GotFocus="textboxes_gotFocus" LostFocus="textboxes_lostFocus"/>
<TextBlock Margin="48,0,0,0" Text="Is Paid" VerticalAlignment="Center" FontWeight="Bold" FontSize="18" Foreground="#FF818181"/>
<CheckBox Margin="16,0,0,0" Height="35" Width="35" BorderBrush="{x:Null}" Style="{DynamicResource flat_ui_checkboxes}"></CheckBox>
</StackPanel>
<GroupBox Header="Product" Margin="150,35,150,0" Foreground="#FF7E7E7E" FontSize="24" FontWeight="DemiBold">
<DataGrid x:Name="product_grid" ItemsSource="{Binding product_data,Mode=TwoWay}" HorizontalAlignment="Center" Margin="0,0,0,0" Height=" 350" Background="White" Width="973.5" AutoGenerateColumns="False" CanUserAddRows="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name,Mode=TwoWay}" ></DataGridTextColumn>
<DataGridTextColumn Header="Brand" Binding="{Binding Brand,Mode=TwoWay}"></DataGridTextColumn>
<DataGridTextColumn Header="Price" Binding="{Binding Price,Mode=TwoWay}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</GroupBox>
<Button Width="200" Height="55" Background="#FF2DCC70" Margin="0,0,0,0" Template="{DynamicResource flat_add_green_btn}" Command="{Binding Add_Customer_Command}" Click="Button_Click" />
</StackPanel>
</Grid>
首先,当您的
Pricesrc
发生更改时,您应该使用PropertyChanged
事件:
private int _Pricesrc;
public int Pricesrc
{
get { return _Pricesrc; }
set { _Pricesrc = value; onPropertyChanged(nameof(Pricesrc)); }
}
这是必需的,因此当您设置总绑定时会更新
现在,为了在您的收藏更改时(当添加或删除项目时)更新Pricesrc
,您应该处理收藏事件,该事件准确地通知-CollectionChanged
在构造函数中添加事件处理程序:
public ViewModel()
{
listsrc = new ObservableCollection<Pages.Product.product_data>();
listsrc.CollectionChanged += OnCollectionChanged;
}
private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
Pricesrc = listsrc.Sum(prod => prod.Price);
}
公共视图模型()
{
listsrc=新的ObservableCollection();
listsrc.CollectionChanged+=OnCollectionChanged;
}
CollectionChanged的私有void(对象发送方,NotifyCollectionChangedEventArgs e)
{
Pricesrc=listsrc.Sum(prod=>prod.Price);
}
编辑:如果您想在现有产品的价格发生变化时更新总价,您应该在
product\u数据
类中实现INotifyPropertyChanged,并在price
属性发生变化时引发事件,类似于我在这里对Pricesrc
属性所做的操作。然后处理该事件并更新总价。当您的Pricesrc
发生更改时,首先应使用PropertyChanged
事件:
private int _Pricesrc;
public int Pricesrc
{
get { return _Pricesrc; }
set { _Pricesrc = value; onPropertyChanged(nameof(Pricesrc)); }
}
这是必需的,因此当您设置总绑定时会更新
现在,为了在您的收藏更改时(当添加或删除项目时)更新Pricesrc
,您应该处理收藏事件,该事件准确地通知-CollectionChanged
在构造函数中添加事件处理程序:
public ViewModel()
{
listsrc = new ObservableCollection<Pages.Product.product_data>();
listsrc.CollectionChanged += OnCollectionChanged;
}
private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
Pricesrc = listsrc.Sum(prod => prod.Price);
}
公共视图模型()
{
listsrc=新的ObservableCollection();
listsrc.CollectionChanged+=OnCollectionChanged;
}
CollectionChanged的私有void(对象发送方,NotifyCollectionChangedEventArgs e)
{
Pricesrc=listsrc.Sum(prod=>prod.Price);
}
编辑:如果您想在现有产品的价格发生变化时更新总价,您应该在
product\u数据
类中实现INotifyPropertyChanged,并在price
属性发生变化时引发事件,类似于我在这里对Pricesrc
属性所做的操作。然后处理该事件并更新总价。感谢您的回复,它解决了问题,但有一点是“最后一行网格的价格没有添加…任何解决方案???…您能解释什么是”Pricesrc=listsrc.Sum(prod=>prod.price)“真的……再次感谢。当我单击空列时,事件会被触发,但添加行时不会触发。哦,我没有看到Price属性是string。求和(或完全更改属性类型)时,应将其转换为适当的数字类型(如int或double)。Sum基本上是对给定属性的值求和,而IEnumerable(即列表、数组等)。感谢您的回复,它解决了问题,但剩下的一件事是“没有添加网格的最后一行价格…任何解决方案???…您能解释什么是”Pricesrc=listsrc.Sum(prod=>prod.price)“真的……再次感谢。当我单击空列时,事件会被触发,但添加行时不会触发。哦,我没有看到Price属性是string。求和(或完全更改属性类型)时,应将其转换为适当的数字类型(如int或double)。Sum基本上是对while IEnumerable(即列表、数组等)的给定属性的值求和。