动态属性创建

时间:2018-02-20 17:51:54

标签: c# asp.net-mvc

让我试着说明一个例子。

我有一个名为Grades的数据库表。这是目前的样子。

|    Id    |         Grade       |
      1         Exceeds Standards
      2         Meets Standards
      3         Below Standards

现在我的代码看起来像这样:

var myTestingExample = db.AnotherTable.Where(x => myList.Contains(x.FirstForeignKeyId))
    .GroupBy(x => new { x.SecondForeignKey.Value, x.SecondTable.Name})
    .Select(
        x =>
            new MyViewModelClass()
            {
                Id = x.Key.Value,
                Name = x.Key.Name,
                CountName = x.Count(),
                CountBelowStandards = x.Count(y => y.GradingSystemId.Value == 3),
                CountMeetsStandards = x.Count(y => y.GradingSystemId.Value == 2),
                CountExceedsStandards = x.Count(y => y.GradingSystemId.Value == 1)
            }).ToList();

现在我担心的是,如果用户想要创建另一个Grade ..那么我将不得不手动将另一个属性添加到MyViewModelClass,然后必须在上面的代码中添加另一行代码得到计数..我真的希望这是动态的,所以我不必为我的视图模型类添加属性。

如何实现这一目标?

1 个答案:

答案 0 :(得分:0)

做你想做的事涉及引入继承。见下文

public class SomeViewModel : INotifyPropertyChanged
{
    private ObservableCollection<IGrade> grades;

    public SomeViewModel()
    {
        Grades = new ObservableCollection<IGrade>()
        {
            new Grade(1, "BelowStandards"), 
            new Grade(2, "MeetsStandards"), 
            new Grade(3, "AboveStandards") 
        };
    }

    // Add new grade here.
    public void AddGrade(string name)
    {
        if (Grades == null)
            throw new ArgumentNullException("can't be null here");

        Grades.Add(new Grade(Greads.Count + 1, name));
    }

    public ObservableCollection<IGrade> Grades 
    {
        get { return grades; }
        set { SetField(ref grades, value, "Grades"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    protected bool SetField<T>(ref T field, T value, string propertyName)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}

public interface IGrade : INotifyPropertyChanged
{
    int Id { get; }
    string Name { get; }
}

public class Grade : IGrade 
{
    public Grade(int id, string name)
    {
        Id = id; 
        Name = name;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    protected bool SetField<T>(ref T field, T value, string propertyName)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    private int id;
    public int Id
    {
        get { return id; }
        set { SetField(ref id, value, "Id"); }
    }

    private string name;
    public string Name
    {
        get { return name; }
        set { SetField(ref name, value, "Name"); }
    }
}

然后在您的XAML中,绑定到相关的Grade属性。因此,当用户添加新成绩时,会显示该成绩。快乐的日子。

我没有测试过这段代码,但是它应该可行,或者至少能给你正确的方法去做你想做的事情。

如果用户想要在运行时更改成绩的名称,这也应该与上面的代码一起使用。