C#WPF DataGridTextColumn自定义属性

时间:2016-11-14 02:10:33

标签: c# wpf data-binding

我试图将数据绑定到某种自定义依赖项属性或WPF中的附加属性。我使用了以下问题 并回答 - How to create Custom Property for WPF DataGridTextColumn  作为一个参考框架,但我需要绑定到标签'在WPF中。我们可以称之为任何东西,但我称之为简单标记,因为我在代码的其他部分使用了一些复选框和文本框。我的班级如下:

public class TagTextColumns : DependencyObject
{
    public static readonly DependencyProperty TagProperty = DependencyProperty.RegisterAttached(
        "Tag",
        typeof(object),
        typeof(DataGridColumn),
        new FrameworkPropertyMetadata(null));

    public static object GetTag(DependencyObject dependencyObject)
    {
        return dependencyObject.GetValue(TagProperty);
    }

    public static void SetTag(DependencyObject dependencyObject, object value)
    {
        dependencyObject.SetValue(TagProperty, value);
    }
}

我想在WPF中将我的DataGridTextColumn设置为类似于以下内容:

<DataGridTextColumn Binding="{Binding Customer}" Header="Customer" local:TagTextColumns.Tag="{Binding tkey}"/>

其中tkey是db中的引用。我这样做是为了计算每行最后一列的小计。现在,我使用DataGridTemplateColumn内置TextBox所以我可以使用t Tag  我还在TechNet上阅读了有关这些内容的内容,但似乎很少指出我想在这里做什么。我甚至不确定它是否可能,但它看起来似乎是这样。

编辑:

这是我尝试在CellEditEnding解雇时调用标记的代码

private void resultsDg_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
    {
        MessageBox.Show(TagTextColumns.GetTag(sender as DataGridTextColumn).ToString());
    }

有关手头问题的更多详情: 我正在尝试从数据库中的四个字段动态计算用户进行更改时最后一列的小计。我试图使用Linq to SQL,但使用System.Data.SqlClientSystem.Data要快得多。也许有人可以告诉我一个更好的方法。计算代码如下:

    private void CalculateAscessorials(string tkey)
    {
        decimal SplitTerm = Properties.Settings.Default.SplitTerminal;
        decimal SplitDrop = Properties.Settings.Default.SplitDrop;
        decimal SiteSplit = Properties.Settings.Default.OnSiteSplit;
        decimal Trainer = Properties.Settings.Default.TrainerLoad;
        decimal WaitTime = Properties.Settings.Default.TerminalWait;
        decimal PumpOut = Properties.Settings.Default.PumpOut;

        DataRow[] row = resultDetail.Select("tkey = " + tkey);

        decimal payRate;
        decimal tempLineItem;
        Decimal.TryParse(row[0]["PayForLine"].ToString(), out tempLineItem);
        Decimal.TryParse(row[0]["PayRate"].ToString(), out payRate);
        if (payRate == 0 && tempLineItem > 0) //this change affts if the rate is 0, that is no rate defined, the rate entered becomes the pay rate for that line only for calculations
            row[0]["PayRate"] = tempLineItem;
        if (!Convert.ToBoolean(row[0]["SplitDrop"]))
        {
            Decimal.TryParse(row[0]["PayRate"].ToString(), out payRate); 
        }
        else if (Convert.ToBoolean(row[0]["SplitDrop"]))
        {
            payRate = SplitDrop;
        }
        //decimal linePay;
        //    Decimal.TryParse(row[0]["PayForLine"].ToString(), out linePay);
        int terms;
        Int32.TryParse(row[0]["SplitLoad"].ToString(), out terms);
        decimal waits;
        Decimal.TryParse(row[0]["WaitTime"].ToString(), out waits);
        int pumps;
        Int32.TryParse(row[0]["PumpOut"].ToString(), out pumps);
        int sites;
        Int32.TryParse(row[0]["SiteSplit"].ToString(), out sites);
        int trainings;
        Int32.TryParse(row[0]["Trainer"].ToString(), out trainings);
        row[0]["PayForLine"] =
                    (SplitTerm * terms)
                    + (waits * WaitTime)
                    + (pumps * PumpOut)
                    + (sites * SiteSplit)
                    + (trainings * Trainer)
                    + payRate;
    }

1 个答案:

答案 0 :(得分:0)

您可以使用MVVM模式计算ViewModel中的小计。这是一个可以引导您走向正确方向的示例。在MainView的构造函数中,我创建了2个课程并应用了学生。课程有一个属性TotalWeight,用于计算所有学生的总体重。如果学生的体重发生变化,或者学生被添加/删除到课程中,我们必须更新UI上的值。这归因于INotifyPropertyChangedObservableCollection

如果您使用LinqToSQL甚至更好的EntityFramework,您可以从商店获得。您可以将其作为实际模型注入ViewModel构造函数。也许你甚至想为此目的引入一个MainViewModel。为简单起见,我跳过了这个。但是你可能想看看dependency injection

XAML:

    <DataGrid ItemsSource="{Binding}">
        <DataGrid.RowDetailsTemplate>
            <DataTemplate>
                <DataGrid ItemsSource="{Binding Students}"></DataGrid>
            </DataTemplate>
        </DataGrid.RowDetailsTemplate>
    </DataGrid>
代码背后的代码:

public class CourseViewModel : ViewModelBase
{
    #region Fields

    private string _name;

    private ObservableCollection<StudentViewModel> _students;

    #endregion Fields

    #region Constructors

    public CourseViewModel()
    {
        _students = new ObservableCollection<StudentViewModel>();
        _students.CollectionChanged += _students_CollectionChanged;
    }

    #endregion Constructors

    #region Properties

    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
            OnPropertyChanged();
        }
    }

    public ObservableCollection<StudentViewModel> Students
    {
        get
        {
            return _students;
        }
    }

    public double TotalWeight
    {
        get
        {
            return Students.Sum(x => x.Weight);
        }
    }

    #endregion Properties

    #region Methods

    private void _students_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {

        // add/remove property changed handlers to students 
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
        {
            foreach (StudentViewModel student in e.NewItems)
            {
                student.PropertyChanged += Student_PropertyChanged;
            }
        }
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
        {
            foreach (StudentViewModel student in e.OldItems)
            {
                student.PropertyChanged -= Student_PropertyChanged;
            }
        }

        //students were added or removed to the course -> inform "listeners" that TotalWeight has changed
        OnPropertyChanged(nameof(TotalWeight));
    }

    private void Student_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        //the weight of a student has changed -> inform "listeners" that TotalWeight has changed
        if (e.PropertyName == nameof(StudentViewModel.Weight))
        {
            OnPropertyChanged(nameof(TotalWeight));
        }
    }

    #endregion Methods
}

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{

    #region Constructors

    public MainWindow()
    {
        InitializeComponent();


        var course1 = new CourseViewModel() { Name = "Course1" };
        course1.Students.Add(new StudentViewModel() { Weight = 100, Name = "Mark" });
        course1.Students.Add(new StudentViewModel() { Weight = 120, Name = "Olaf" });
        course1.Students.Add(new StudentViewModel() { Weight = 111, Name = "Hans" });
        var course2 = new CourseViewModel() { Name = "Course2" };
        course2.Students.Add(new StudentViewModel() { Weight = 100, Name = "Mark" });
        course2.Students.Add(new StudentViewModel() { Weight = 90, Name = "Renate" });
        course2.Students.Add(new StudentViewModel() { Weight = 78, Name = "Judy" });

        DataContext = new List<CourseViewModel>()
        {
            course1,
            course2
        };
    }

    #endregion Constructors


}
public class StudentViewModel : ViewModelBase
{
    #region Fields

    private string _name;
    private double _weight;

    #endregion Fields

    #region Properties

    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
            OnPropertyChanged();
        }
    }

    public double Weight
    {
        get
        {
            return _weight;
        }
        set
        {
            _weight = value;
            OnPropertyChanged();
        }
    }

    #endregion Properties
}
相关问题