我需要社区的帮助。我试图在DataGrid(WPF和C#)中乘以两列的值,第一列从MySql数据库获取其数据,第二列是输入值,用户将键入一个应与数字相乘的数字第一列和结果应显示在名为" Total"的第三列中。我已经搜索过所有尝试过几乎相同的其他人的不同方法,但我只是不能得到乘法的值,结果出现在第三列。这是我尝试过的最后一段代码,我不得不提到我对C#和WPF还很新,但经验并不多:
<DataGrid AutoGenerateColumns="False" x:Name="tblData" Margin="30,197,7,0" Grid.Row="1" VerticalAlignment="Top" Height="510" Grid.ColumnSpan="4"
BorderThickness="2" BorderBrush="#FF445BBF" ItemsSource="{Binding Path=LoadDataBinding}" CanUserResizeRows="False" ClipToBounds="True"
CanUserSortColumns="False" HorizontalGridLinesBrush="#FFC7C7C7" VerticalGridLinesBrush="#FFC7C7C7" IsManipulationEnabled="True" EnableRowVirtualization="False"
IsTextSearchEnabled="True" xmlns:local="clr-namespace:PoS_Pimentel">
<DataGrid.Resources>
<local:AmmountConverter x:Key="AmmountConverter" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=nomprod}" Header="Producto" Width="500" IsReadOnly="True">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="14" />
</Style>
</DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Path=preciogram, Mode=TwoWay}" Header="Precio por Gramo" Width="190" IsReadOnly="True">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="14" />
</Style>
</DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Path=gramos, Mode=TwoWay}" Header="Gramos" Width="190" IsReadOnly="False">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="14" />
</Style>
</DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Path=total, Mode=TwoWay}" Header="Total" Width="*" IsReadOnly="True">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="14" />
</Style>
</DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
在C#端,我为EntitiyClass和AmmountConverter类创建了两个单独的.cs文件:
EntityClass代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Windows.Forms;
namespace PoS
{
#region
public class Entity_Class : INotifyPropertyChanged
{
private int _preciogram;
public int PrecioGram
{
get { return _preciogram; }
set { _preciogram = value; NotifyPropertyChanged("gramos"); }
}
private int _gramos;
public int Gramos
{
get { return _gramos; }
set { _gramos = value; NotifyPropertyChanged("gramos"); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if(PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
和AmmountConverter类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace PoS_Pimentel
{
public class AmmountConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double prcgrms = values[1] == null ? 0 : System.Convert.ToDouble(values[1]);
double grms = values[2] == null ? 0 : System.Convert.ToDouble(values[2]);
return prcgrms * grms;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
我不是很擅长这个,但我正在努力,任何指针都会非常感激。谢谢大家。
答案 0 :(得分:3)
您无需使用转换器进行此计算。希望你能在Model Class中处理它。您还需要绑定到属性。 DataGrid绑定属性名称不正确c#区分大小写。请参阅下面的代码。
<DataGrid x:Name="dgr" AutoGenerateColumns="False" ItemsSource="{Binding LoadDataBinding}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=PrecioGram, Mode=TwoWay}" Header="Precio por Gramo" Width="190" IsReadOnly="True">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="14" />
</Style>
</DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Path=Gramos, Mode=TwoWay}" Header="Gramos" Width="190" IsReadOnly="False">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="14" />
</Style>
</DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Total" Width="100" Binding="{Binding Total}">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="14" />
</Style>
</DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainViewModel();
}
}
public class MainViewModel
{
private ObservableCollection<Entity_Class> myVar = new ObservableCollection<Entity_Class>();
public ObservableCollection<Entity_Class> LoadDataBinding
{
get { return myVar; }
set { myVar = value; }
}
public MainViewModel()
{
for (int i = 1; i < 10; i++)
{
LoadDataBinding.Add(new Entity_Class() { PrecioGram=i});
}
}
}
public class Entity_Class : INotifyPropertyChanged
{
private int _preciogram;
public int PrecioGram
{
get { return _preciogram; }
set { _preciogram = value; NotifyPropertyChanged("PrecioGram"); }
}
private int _gramos;
public int Gramos
{
get { return _gramos; }
set
{
_gramos = value; NotifyPropertyChanged("gramos");
Total = _preciogram * _gramos;
}
}
private int _total;
public int Total
{
get { return _total; }
set { _total = value; NotifyPropertyChanged("Total"); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
答案 1 :(得分:1)
有两种方法可以实现这一点,看起来你正试图混合使用它们。
一种方法是将所有3列绑定到数据对象上的属性,并在用户输入的属性上使用PropertyChange事件处理程序来重新计算总列。这通常是我的偏好。
<DataGridTextColumn Binding="{Binding Value1}" />
<DataGridTextColumn Binding="{Binding Value2}" />
<DataGridTextColumn Binding="{Binding Total}" />
private void MyDataItem_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Value2")
Total = Value1 * Value2;
}
采用这种方法,不需要转换器。
另一种方法是不绑定第3列,并使用转换器显示它
<!-- Note: syntax may be incorrect here -->
<DataGridTextColumn Binding="{Binding Value1}" />
<DataGridTextColumn Binding="{Binding Value2}" />
<DataGridTextColumn>
<DataGridTextColumn.Binding>
<Multibinding Converter="{StaticResource MyMultiplicationConverter}">
<Binding Path="Value1" />
<Binding Path="Value2" />
</Multibinding>
<DataGridTextColumn.Binding>
</DataGridTextColumn>
在这种情况下,我们将两列绑定到数据模型上的值,第三列使用转换器将两个值转换为不同的第三个值。
应该注意的是,无论您使用哪种方法,TextBox的默认绑定模式只是更新LostFocus
上的源,因此我们不会引发过多的更改通知。如果您希望在用户输入数据时实时更新,则应将绑定模式更改为PropertyChanged
或write your own binding update behavior to update the bound source after a short delay。
另外作为旁注,您正在为PrecioGram
属性中的错误属性提出PropertyChange通知:
public int PrecioGram
{
get { return _preciogram; }
set
{
_preciogram = value;
NotifyPropertyChanged("gramos"); // Incorrect property here
}
}