【问题标题】:DataGrid Multiplicating Two ColumnsDataGrid乘以两列
【发布时间】:2015-05-11 00:22:23
【问题描述】:

我需要社区的帮助。我正在尝试将 DataGrid(WPF 和 C#)中两列的值相乘,第一列从 MySql 数据库中获取其数据,第二列是输入值,用户将在其中键入一个应乘以的数字第一列,结果应显示在名为“总计”的第三列中。我进行了全面搜索,并尝试了与其他尝试几乎相同事情的人不同的方法,但我就是无法将值相乘并且结果出现在第三列中。这是我尝试过的最后一段代码,我不得不提一下,我对 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 文件:

实体类代码:

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();
        }
    }
}

我不是很擅长这个,但我正在尝试,任何指针将不胜感激。谢谢大家。

【问题讨论】:

  • 我什至尝试了这篇文章中的解决方案,但也没有用:link
  • 您在哪里使用 AmmountConverter ?在总列中,您没有使用转换器。
  • 哦,是的,抱歉,我忘了包含这段代码,但是它告诉我找不到 AmmountConverter。
  • 您已将转换器创建为数据网格的资源。但是您还没有使用转换器来计算总数。我也不确定你的转换器声明。

标签: c# wpf datagrid


【解决方案1】:

您不需要使用转换器来进行此计算。希望您可以在模型类中处理它。您还需要绑定到属性。 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));
        }
    }
}

【讨论】:

  • 这也可以正常工作,尽管我个人不喜欢我的属性设置器中的任何非标准代码。我宁愿使用 PropertyChanged 事件处理程序 :)
  • 我希望 PropertyChanged 事件也从 PropertySetter 中引发 :)
  • 我发现这个效果很好,但是随着循环中生成的数字(从 0 到 9),它实际上会成倍增加,但它似乎不想处理我从db 表示“精确图”
  • 我终于成功了,谢谢你的帮助! @灯开关
【解决方案2】:

有两种方法可以做到这一点,看起来您正在尝试混合使用这两种方法。

一种方法是将所有 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;
}

使用这种方法,不需要转换器。


另一种方法是不绑定第三列,使用转换器显示

<!-- 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 上的源,因此我们不会发出过多的更改通知。如果您希望它在用户输入数据时实时更新,您应该将绑定模式更改为PropertyChangedwrite 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
    }
}

【讨论】:

  • In 是“数据”,与“绑定”相同,因为我没有得到选项,如果我输入它,它会将其标记为错误?
  • @hectormtnezg 是的,很抱歉那个错字,我会改掉的 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-04
  • 2018-06-26
  • 1970-01-01
  • 2015-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多