Привязка данных к вычисляемому полю - PullRequest
4 голосов
/ 26 марта 2011

Я столкнулся с небольшой проблемой, когда пытаюсь привязать DataTextColumn DataGrid к вычисляемому полю.

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>

Где Student - это объект Entity с одним небольшим дополнением. TotalCosts не является полем в таблицах БД, поэтому для этого я создал частичный класс.

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

Проблема, с которой я сталкиваюсь, заключается в том, что TotalCosts не обновляется автоматически при заполнении любого из других полей. Я предполагаю, что это потому, что он не указан как свойство зависимости. Как я могу решить это для свойства, где нет набора?

Ответы [ 4 ]

3 голосов
/ 17 октября 2012

Здравствуйте, я думаю, что могу помочь вам, у меня есть этот код для базы данных в 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 в столбце A и 5 в столбце B затем я просто нажимаю клавишу Tab, чтобы перейти к столбцу C, и значение 2 появляется автоматически не нужно нажимать на другую строку или нажимать ввод.

ColumnC - это вычисляемый столбец с выражением (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>
3 голосов
/ 26 марта 2011

Вы можете вызвать OnPropertyChanged("TotalCosts") в установщиках каждого свойства, от которого зависит TotalCosts, это обновит привязку

3 голосов
/ 26 марта 2011

Я предполагаю, что Студент реализует INotifyPropertyChanged.Вам нужно зарегистрироваться на событие PropertyChanged для LodgingCosts + RegistrationCosts + TravelCosts + DiningCosts и вызвать событие PropertyChanged для TotalCosts.

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 голосов
/ 26 марта 2011

Вам необходимо реализовать 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 текстовых поля .. и нажмите кнопку, чтобы увидеть значение человека P1 ..u найдет вычисленное поле со значением .. надеюсь, это поможет вам .. Спасибо, BHavik

...