1

私はいくつかのコードを移行しており、適切にフォーマットされたルックアップ テーブルを持っていますが、下位互換性のために使用するために古風な構造に変換する必要があります。

SelectItemList のリストを取得する GetLookupTable() メソッドがあります。すべてのモデルとルックアップ呼び出しはコード生成されますが、返される SelectItem の一部を手動で変更する必要があるため、開発者が実装できるビジター パターンを実装しました。彼らは望んでいます。

ビジターは部分メソッドとして実行され、開発者が実装したい場合は実装できますが、以下に示すようにエラーが発生します

エラー 132 メソッド 'InfoChoice.Web.Admin.ViewModels.Product.ProductCreditCardViewModel.LookupTableViewModel.CardTypeVisit(System.Web.Mvc.SelectListItem)' からデリゲートを作成できません。実装宣言のない部分メソッドであるためです。

Razorを使用した呼び出しコードは次のとおりです

<div class='row'>
    <label>Card Type</label>
    @Html.CheckBoxListFor(model => model.CardType, @Model.LookupTable.CardType)
    David Says: @Model.CardType
</div>

ここに簡素化されたモデルがあります

// Generated model
public partial class ProductCreditCardViewModel
{
    [Required]
    [DisplayName("Account - Card Type")]
    [DefaultValue("")]
    public string CardType { get; set; }


    // ***************************************************************************************************
    // Lookup Table calls for this model (Generated)
    // ***************************************************************************************************
    public partial class LookupTableViewModel : BaseLookupTableViewModel
    {
        partial void CardTypeVisit(SelectListItem item);

        public SelectList CardType
        {
            get
            {
                return GetLookupItems("ProductCreditCardCardType", CardTypeVisit);
            }
        }
    }

}

public partial class ProductCreditCardViewModel
{
    // Custom Implementation Goes Here
    public partial class LookupTableViewModel : BaseLookupTableViewModel
    {
        //partial void CardTypeVisit(SelectListItem item)
        //{
        //    item.Value = "|" + item.Value + "|";
        //}
    }
}

Select Item List データを返すベース LookupTable ビュー モデル

public class BaseLookupTableViewModel
{
    public SelectList GetLookupItems(string lookupName)
    {
        return GetLookupItems(lookupName, "Name", "Text", null, null);
    }
    public SelectList GetLookupItems(string lookupName, Action<SelectListItem> itemVisitor)
    {
        return GetLookupItems(lookupName, "Name", "Text", null, itemVisitor);
    }
    public SelectList GetLookupItems(string lookupName, string dataValueField, string dataTextField, object selectedValue, Action<SelectListItem> itemVisitor)
    {
        // Go get some data from DataStore
        var list = App.Data.Lookup.GetLookupList(lookupName);

        // Convert to IEnumerable<SelectItemList>
        var result = new SelectList(list, dataValueField, dataTextField, selectedValue);

        // If developer would like to alter that list before it is returned, then developer should implement an item visitor
        if (itemVisitor != null)
        {
            foreach (var item in result)
            {
                itemVisitor(item);
            }
        }

        return result;
    }

    public void SampleVisitor(SelectListItem item)
    {
        item.Value = "Modified: " + item.Value;
    }
}
4

1 に答える 1

1

エラーは正しいです。実装されていない場合、部分メソッドは存在しないため、デリゲートをそのようにバインドすることはできません。ここでの最善のオプションは、おそらくスイッチ(または同様のもの)に基づいて手動で呼び出すか、本当にデリゲートが必要な場合は、リフレクションを使用してメソッドを探し(非パブリックバインディングフラグを指定することを忘れないでください)Delegate.CreateDelegate、メソッドがifを使用することです。存在することが判明しました。または怠惰なオプション:

private void OnCardTypeVisit(SelectListItem item) { CardTypeVisit(item); }
partial void CardTypeVisit(SelectListItem item);

OnCardTypeVisitデリゲートをの代わりにバインドしますCardTypeVisit

デリゲートに関しては、これは間接デリゲートに変更するのと同じくらい簡単な場合もあります。これは、On*アプローチと非常によく似ています。

return GetLookupItems("ProductCreditCardCardType", x => CardTypeVisit(x));

(ただし、それがデリゲートではなくである場合、失敗が予想されます)

于 2011-06-28T08:22:13.573 に答える