編集:このトピックについて十分なフィードバックを得たので、ブログ投稿 に値すると感じました
ドメイン オブジェクトを ddl コントロールにバインドするときにとったアプローチの 1 つは、constr にオーバーロードがある基本クラスから継承して、元のテキスト/値のみの「サブセット」を許可することです。以下のコードは、モデル ビュー プレゼンターまたはモデル ビュー ビューモデルの実装で使用され、ddl コントロールを抽象化して、このビジネス コードの上に任意の UI をプッシュできるようにします。
以下は、ddl をユーザー オブジェクトのコレクションにバインドし、関連するオブジェクト (作業単位) に基づいて選択したオブジェクトを設定する方法の例です。
public void PopulateUserDDL(UnitOfWork UnitOfWorkObject)
{
List<User> UserCollection = mUserService.GetUserCollection(); //get a collection of objects to bind this ddl
List<ILookupDTO> UserLookupDTO = new List<ILookupDTO>();
UserLookupDTO.Add(new User(" ", "0"));
//insert a blank row ... if you are into that type of thing
foreach (var User in UserCollection) {
UserLookupDTO.Add(new User(User.FullName, User.ID.ToString()));
}
LookupCollection LookupCollectionObject = new LookupCollection(UserLookupDTO);
LookupCollectionObject.BindTo(mView.UserList);
if (UnitOfWorkObject == null) {
return;
}
if (UserCollection == null) {
return;
}
for (i = 0; i <= UserCollection.Count - 1; i++) {
if (UserCollection(i).ID == UnitOfWorkObject.User.ID) {
LookupCollectionObject.SelectedIndex = (i + 1);
//because we start at 0 instead of 1 (we inserted the blank row above)
break;
}
}
}
以下は、ユーザーオブジェクトでオーバーロードがどのように見えるかです
/// <summary>
/// This constr is used when you want to create a new Lookup Collection of ILookupDTO
/// </summary>
/// <param name="txt">The text that will show up for the user in the lookup collection</param>
/// <param name="val">The value that will be attached to the item in the lookup collection</param>
/// <remarks></remarks>
public New(string txt, string val) : base(txt, val)
{
}
以下は、エンティティ/ドメイン オブジェクト/DTO/etc の基本クラスで必要になります。
public New(string txt, string val)
{
mText = txt;
mValue = val;
}
この基本クラスは ILookupDTO も実装する必要があります。これは、この例でユーザー オブジェクトによって使用される Text および Value プロパティを公開する必要があるためです。
public interface ILookupDTO
{
string Text {
get;
set;
}
string Value {
get;
set;
}
}
以下は、この回答の上部にある bind メソッドで使用される LookupCollection の定義です
public class LookupCollection
{
private readonly IEnumerable<ILookupDTO> dtos;
private ILookupList mList;
public LookupCollection(IEnumerable<ILookupDTO> dtos)
{
this.dtos = dtos;
}
public void BindTo(ILookupList list)
{
mList = list;
mList.Clear();
foreach (ILookupDTO dto in dtos) {
mList.Add(dto);
}
}
public int SelectedIndex {
get { return mList.SelectedIndex; }
set { mList.SelectedIndex = value; }
}
public string SelectedValue {
get { return mList.SelectedValue; }
set { mList.SelectedValue = value; }
}
}
以下は、ILookupList のインターフェイスです。各 UI 固有のコントロールの実装で使用されます (以下の Web および wpf の例を参照してください)。
public interface ILookupList
{
void Add(ILookupDTO dto);
void Clear();
int Count();
int SelectedIndex {
get;
set;
}
string SelectedValue {
get;
set;
}
}
コードビハインドで、ビューの読み取り専用プロパティで次のようなことを行う必要があります
新しい WebLookupList(ddlUsers) を返す
これはWeb固有のddlの実装です
public class WebLookupList : ILookupList
{
private readonly ListControl listControl;
public WebLookupList(ListControl listControl)
{
this.listControl = listControl;
}
public void Clear()
{
listControl.Items.Clear();
}
public void Add(Interfaces.ILookupDTO dto)
{
listControl.Items.Add(new ListItem(dto.Text, dto.Value));
}
public int Count()
{
return listControl.Items.Count;
}
public int SelectedIndex {
get { return listControl.SelectedIndex; }
set { listControl.SelectedIndex = value; }
}
public string SelectedValue {
get { return listControl.SelectedValue; }
set { listControl.SelectedValue = value; }
}
}
ビューの読み取り専用プロパティが wpf を使用する場合の WPF 固有の ddl の実装は次の
とおりです - Return New WPFLookupList(ddlUsers)
public class WPFLookupList : ILookupList
{
private readonly ComboBox combobox;
public WPFLookupList(ComboBox combobox)
{
this.combobox = combobox;
}
public void Add(Interfaces.ILookupDTO dto)
{
ComboBoxItem item = new ComboBoxItem();
item.Content = dto.Text;
item.Tag = dto.Value;
combobox.Items.Add(item);
}
public void Clear()
{
combobox.Items.Clear();
}
public int Count()
{
return combobox.Items.Count;
}
public int SelectedIndex {
get { return combobox.SelectedIndex; }
set { combobox.SelectedIndex = value; }
}
public string SelectedValue {
get { return combobox.SelectedValue.Tag; }
set { combobox.SelectedValue.Tag = value; }
}
}
一度に必要なのはこれらのうちの 1 つだけですが、両方を表示すると、何を抽象化しているのかが明確になると思いました
これは非常に大きな答えだったので、リクエストがあれば、これが実際に動作していることを示すダウンロード用のサンプル プロジェクトを投稿できます - お知らせください