如何在WebGrid中为列标题使用DisplayName数据注释?

时间:2011-03-09 18:55:44

标签: asp.net asp.net-mvc-3 data-annotations webgrid

我有一个Car类,我试图使用WebGrid助手在MVC 3视图中显示。下面是Car及其元数据类。

汽车类:

[MetadataType(typeof(CarMetadata))]
public partial class Car
{
    // car implementation
}

汽车元数据类:

public class CarMetadata
{        
    [DisplayName("Car Name")]
    [StringLength(100, ErrorMessageResourceType = typeof(ValidationText), ErrorMessageResourceName="CarNameDescriptionLength")]
    [Required]
    public string CarName { get; set; }    
}

查看内容:

@model List<Car>
...
var grid = new WebGrid(Model, canPage: true, rowsPerPage: 10);
grid.Pager(WebGridPagerModes.NextPrevious);

@grid.GetHtml(
    htmlAttributes: new { id = "grid" },
    columns: grid.Columns(
        grid.Column("CarName", ?????)
    ));

目标:我想弄清楚如何使用DisplayName数据注释作为WebGrid中的列标题文本( ????? )。有谁知道这是如何实现的?

提前致谢!

2 个答案:

答案 0 :(得分:11)

丑陋但是它可以起作用:

grid.Column(
    "CarName", 
    ModelMetadata.FromLambdaExpression(
        car => car.CarName, 
        new ViewDataDictionary<Car>(new Car())
    ).DisplayName
)

问题是WebGrid助手完全基于动态数据,绝对没有强类型,这也是我讨厌它的原因之一。 Microsoft的WebMatrix团队必须是C#4.0动态功能的真正粉丝,因为他们的整个API只接受弱类型的对象: - )

MvcContrib Grid要好得多。

答案 1 :(得分:0)

我已经创建了一个这样的辅助方法:

import UIKit
import CoreData

class WoordTableViewController: UITableViewController, NSFetchedResultsControllerDelegate, UITextFieldDelegate {

    @IBOutlet weak var woordTextField: UITextField!


    var lijst: LijstMO!
    var woord: WoordMO!
    var woordeninlijst: [WoordMO] = []
    var fetchResultController: NSFetchedResultsController<WoordMO>!



    override func viewDidLoad() {
        super.viewDidLoad()

        title = lijst.naam
        self.woordTextField.delegate = self

        let fetchRequest: NSFetchRequest<WoordMO> = WoordMO.fetchRequest()
        let sortDescriptor = NSSortDescriptor(key: "naam", ascending: true)
        fetchRequest.sortDescriptors = [sortDescriptor]

        if let appDelegate = (UIApplication.shared.delegate as? AppDelegate) {
            let context = appDelegate.persistentContainer.viewContext
            fetchResultController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
            fetchResultController.delegate = self

            do {
                try fetchResultController.performFetch()
                if let fetchedObjects = fetchResultController.fetchedObjects {
                    woordeninlijst = fetchedObjects
                }
            } catch {
                print(error)
            }
        }

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        self.navigationItem.rightBarButtonItem = self.editButtonItem
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {

        // foutmelding leeg woord
        if woordTextField.text == "" {
            let alertController = UIAlertController(title: "Oooo Neeeee", message: "Zonder tekst kunnen we dit woord echt niet opslaan. Geef 'm een mooie naam en druk op Bewaar. Ka-tching! ", preferredStyle: .alert)
            let alertAction = UIAlertAction(title: "Okidoki", style: .default, handler: nil)
            alertController.addAction(alertAction)
            present(alertController, animated: true, completion: nil)

            return false
        }

        else {
        print("Woord: \(woordTextField.text ?? "")")

        // saving the restaurant to database
        if let appDelegate = (UIApplication.shared.delegate as? AppDelegate) {

            // create new list

            woord = WoordMO(context: appDelegate.persistentContainer.viewContext)
            woord.naam = woordTextField.text
            woord.zitInLijst = lijst
            woordTextField.text = ""


            appDelegate.saveContext()
            print ("WoordMO: \(woord.naam ?? "")")
        }

        return true
        }
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return woordeninlijst.count
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let CellIdentifier = "Cell"
        let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier, for: indexPath) as! WoordTableViewCell

        cell.woordLabel.text = woordeninlijst[indexPath.row].naam

        return cell

    }

    // MARK: NSFetchedResultsControllerDelegate methods

    func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        tableView.beginUpdates()
    }

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {

        switch type {
        case .insert:
            if let newIndexPath = newIndexPath {
                tableView.insertRows(at: [newIndexPath], with: .fade)
            }
        case .delete:
            if let indexPath = indexPath {
                tableView.deleteRows(at: [indexPath], with: .fade)
            }
        case .update:
            if let indexPath = indexPath {
                tableView.reloadRows(at: [indexPath], with: .fade)
            }
        default:
            tableView.reloadData()
        }

        if let fetchedObjects = controller.fetchedObjects {
            woordeninlijst = fetchedObjects as! [WoordMO]
        }
    }

    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        tableView.endUpdates()
    }

并像这样使用它:

public static string GetDisplayName<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> property)
{
    return GetDisplay(property);
}

public static string GetDisplayName<TModel, TProperty>(this HtmlHelper<IEnumerable<TModel>> html, Expression<Func<TModel, TProperty>> property)
{
    return GetDisplay(property);
}

private static string GetDisplay<M,P>(Expression<Func<M,P>> property)
{
    var propertyExp = (MemberExpression)property.Body;
    var member = propertyExp.Member;
    var disp = (DisplayAttribute)member.GetCustomAttribute(typeof(DisplayAttribute));
    if (disp == null)
    {
        return member.Name;
    }
    return disp.Name;
}
相关问题