2011-03-26 61 views
4

我遇到了一个小问题,我尝试将DataGrid的DataTextColumn绑定到计算字段。DataBinding到计算字段

WPF

<DataGrid ItemsSource="{Binding Path=CurrentRoster, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
      AutoGenerateColumns="False" 
      AlternatingRowBackground="Gainsboro" 
      AlternationCount="2"> 
    <DataGrid.Columns> 
    <DataGridComboBoxColumn Header="Student Enrolled" 
          ItemsSource="{Binding Source={StaticResource AvailableStudents}}" 
          SelectedItemBinding="{Binding Path=Student}"> 
    </DataGridComboBoxColumn> 
    <DataGridTextColumn Header="Registration" Binding="{Binding Path=RegistrationCosts, StringFormat='{}{0:C}'}"/> 
    <DataGridTextColumn Header="Lodging" Binding="{Binding Path=LodgingCosts, StringFormat='{}{0:C}'}"/> 
    <DataGridTextColumn Header="Travel" Binding="{Binding Path=TravelCosts, StringFormat='{}{0:C}'}"/> 
    <DataGridTextColumn Header="Dining" Binding="{Binding Path=DiningCosts, StringFormat='{}{0:C}'}"/> 
    <DataGridTextColumn Header="Total Costs" IsReadOnly="True" Binding="{Binding Path=TotalCosts, StringFormat='{}{0:C}'}"/> 
</DataGrid.Columns> 

如果学生是一个小的添加实体对象。 TotalCosts不是数据库表中的字段,所以我为此创建了部分类。

public partial class Student 
{ 
    public Decimal TotalCosts 
    { 
     get { return (LodgingCosts + RegistrationCosts + TravelCosts + DiningCosts); } 
    } 
} 

我遇到的问题是TotalCosts在填写任何其他字段时不会自动更新。我猜这是因为它没有列为依赖项属性。如何解决这个问题,对于没有设置的房产?

回答

3

您可以在TotalCosts取决于每个属性的setter方法调用OnPropertyChanged("TotalCosts"),这将刷新绑定

+0

ü为什么要回答这个问题我回答后? – 2011-03-26 16:36:37

+0

为什么不呢?这不是同一个答案(尽管它也使用OnPropertyCHanged)。我认为最好在setter中做,而不是处理PropertyChanged事件。我不喜欢订阅我自己的活动的想法... – 2011-03-26 16:39:40

+1

是的。现在我注意到了。我假设学生是自动生成的,因此你不能改变Setters。我更喜欢你的想法,但99%的时间不适用(当使用EF,WCF等) – 2011-03-26 16:50:47

3

我假设学生实现INotifyPropertyChanged。你必须做的是注册PropertyChanged事件的LodgingCosts + RegistrationCosts + TravelCosts + DiningCosts,并引发TotalCosts的PropertyChanged事件。

public partial class Student 
{ 
    public Decimal TotalCosts 
    { 
     get { return (LodgingCosts + RegistrationCosts + TravelCosts + DiningCosts); } 
    } 

    public Student() 
    { 
     this.PropertyChanged += new PropertyChangedEventHandler(Student_PropertyChanged); 
    } 

    void Student_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     if (e.PropertyName == "LodgingCosts" || 
      e.PropertyName == "RegistrationCosts" || 
      e.PropertyName == "TravelCosts" || 
      e.PropertyName == "DiningCosts") 
     { 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs("TotalCosts")); 
     } 
    } 

} 
0

你需要实现类上的INotifyPropertyChanged。这里是例子:

public class Person : INotifyPropertyChanged 
{ 
    //public int Id 
    //{ get; set; } 

    //public string Name { get; set; } 

    private int _Id; 

    public int Id 
    { 
     get { return _Id; } 
     set { _Id = value; 
     RaisePropertyChanged("Id"); 
     } 
    } 

    private string _EmpNo 
    { 
     get 
     { 
      return Id.ToString() + Name.ToString(); 
     } 
    } 

    private string _Name; 

    public string Name 
    { 
     get { return _Name; } 
     set 
     { 
      _Name = value; 
      RaisePropertyChanged("Name"); 
     } 
    } 

    private void RaisePropertyChanged(string property) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(property)); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

XAML代码:

<DockPanel> 
    <TextBox Text="{Binding P1.Id}" Height="50" Width="100" DockPanel.Dock="Top" /> 
    <TextBox Text="{Binding P1.Name}" Height="50" Width="100" DockPanel.Dock="Top" /> 
    <Button Content="OK" Click="Button_Click" DockPanel.Dock="Bottom"/> 
</DockPanel> 

测试:

public TestWindow() 
{ 
    InitializeComponent(); 

    this.DataContext = this; 
} 

private Person _P1 = new Person(); 

public Person P1 
{ 
    get { return _P1; } 
    set { _P1 = value; } 
} 

private void Button_Click(object sender, RoutedEventArgs e) 
{ 

} 

类型的东西在2 textboxes..and点击按钮看到了人的价值P1 ..u将找到计算的字段值.. 希望它可以帮助你.. 谢谢, BHavik

3

你好Ø想我可以帮你,我已经在SQLSERVER 数据的基础上这个代码,我有一个数据集的数据源,我的数据库

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 

using TestDeDataGrid.TestDSTableAdapters; 

namespace TestDeDataGrid 
{ 

    public partial class MainWindow : Window 
    { 
     //private ICollection<TablaTest> registros; 

     public MainWindow() 
     { 
      InitializeComponent(); 

      TestDS ds = new TestDS(); 
      TablaTestTableAdapter adapter = new TablaTestTableAdapter(); 
      adapter.Fill(ds.TablaTest); 


      TablaTestGrid.ItemsSource = ds.TablaTest.DefaultView; 
     } 


     private void TablaTestGrid_CurrentCellChanged(object sender, EventArgs e) 
     { 
      if ((String)(((DataGrid)sender).CurrentColumn.Header) == "A/B") 
       ((DataGrid)sender).CommitEdit(DataGridEditingUnit.Row, true); 
     } 
    } 
} 

有了这一招C的自动计算列例如,如果我在列A和列B中输入10,然后我按Tab键移动到列C,并且值2自动出现 不需要单击其他行,然后我在列A和B中输入值 或按回车。列表C是表达式(ColumnaA/ColumnaB)和类型 System.Decimal的计算列。

而且还有我的XAML代码:

<DataGrid Name="TablaTestGrid" Grid.Row="1" AutoGenerateColumns="False"      
       CurrentCellChanged="TablaTestGrid_CurrentCellChanged"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Header="ID" Binding="{Binding Path=IdTablaTest}" IsReadOnly="True"></DataGridTextColumn> 
      <DataGridTextColumn Header="Col A" Binding="{Binding Path=ColumnaA}"></DataGridTextColumn> 
      <DataGridTextColumn Header="Col B" Binding="{Binding Path=ColumnaB}"></DataGridTextColumn> 
      <DataGridTextColumn Header="A/B" Binding="{Binding Path=ColumnaC}" IsReadOnly="True" ></DataGridTextColumn>    
      <DataGridTextColumn Header="TestOnly"></DataGridTextColumn> 
     </DataGrid.Columns> 
    </DataGrid>