我有一个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中的列标题文本( ????? )。有谁知道这是如何实现的?
提前致谢!
答案 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;
}