Привязка объекта с подчиненными объектами в качестве свойств к сетке данных - PullRequest
8 голосов
/ 02 января 2009

Я работаю с объектом, в котором есть дочерние объекты (см. Пример ниже). Я пытаюсь связать List<rootClass> с сеткой данных. Когда я связываю List<>, в ячейке, содержащей subObject, я вижу следующее значение ... "namespace.subObject" ..., строковые значения отображаются правильно.

В идеале я хотел бы видеть свойство «Описание» subObject в ячейке данных. Как я могу сопоставить subObject.Description для отображения в ячейке данных?

public class subObject
{
   int id;
   string description;

   public string Description
   { get { return description; } }
}

public class rootClass
{
   string value1;
   subObject value2;
   string value3;

   public string Value1
   { get { return value1; } }

   public subObject Value2
   { get { return value2; } }

   public string Value3
   { get { return value3; } }
}

Ответы [ 4 ]

9 голосов
/ 03 января 2009

Поскольку вы упоминаете DataGridViewColumn (теги), я предполагаю, что вы имеете в виду winforms.

Доступ к подсвойствам - это боль; валютный менеджер привязан к списку, поэтому по умолчанию у вас есть доступ только к непосредственным свойствам; однако, вы можете обойти это , если вам абсолютно необходимо , используя собственный дескриптор типа. Вам также потребуется использовать другой токен, например, «Foo_Bar» вместо «Foo.Bar». Тем не менее, это основной объем работы, который требует знания PropertyDescriptor, ICustomTypeDescriptor и, вероятно, TypeDescriptionProvider, и почти наверняка не стоит,

Самое простое исправление состоит в том, чтобы выставить свойство как shim / pass-thru:

public string Value2Description {
    get {return Value2.Description;} // maybe a null check too
}

Затем привязать к «Value2Description» и т. Д.

9 голосов
/ 02 января 2009

Если я не ошибаюсь, он показывает результат вызова .ToString () для вашего subObject, так что вы можете переопределить это, чтобы вернуть содержимое Description.

Вы пытались просто привязать Value1.Description? (Я предполагаю, что это не работает).

У меня есть класс, который можно использовать вместо List при связывании, который будет обрабатывать это, он реализует ITypedList, который позволяет коллекции предоставлять больше «свойств» для своих объектов, включая вычисляемые свойства.

Последняя версия имеющихся у меня файлов:

https://gist.github.com/lassevk/64ecea836116882a5d59b0f235858044

Для использования:

List<rootClass> yourList = ...
TypedListWrapper<rootClass> bindableList = new TypedListWrapper<rootClass>(yourList);
bindableList.BindableProperties = "Value1;Value2.Description;Value3.Description";
gridView1.DataSource = bindableList;

По сути, вы привязываетесь к экземпляру TypedList<T> вместо List<T> и настраиваете свойство BindableProperties. У меня есть некоторые изменения в работе, в том числе одно, которое просто автоматически создает BindableProperties, но его пока нет в транке.

Вы также можете добавить рассчитанные свойства, например:

yourList.AddCalculatedProperty<Int32>("DescriptionLength",
    delegate(rootClass rc)
    {
        return rc.Value2.Description.Length;
    });

или с .NET 3.5:

yourList.AddCalculatedProperty<Int32>("DescriptionLength",
    rc => rc.Value2.Description.Length);
3 голосов
/ 02 января 2009

Я не уверен, используете ли вы ASP.NET, но если да, то вы можете использовать столбец шаблона и метод Eval () для отображения значений вложенных объектов. Например. отобразить свойство Description субобъекта:

<asp:GridView ID="grid" runat="server" AutoGenerateColumns="true">
  <Columns>
    <asp:TemplateField>
      <ItemTemplate>
        <asp:Literal Text='<%# Eval("Value2.Description") %>' runat="server" />
      </ItemTemplate>
    </asp:TemplateField>
  </Columns>
</asp:GridView>
1 голос
/ 24 августа 2011

Не уверен, что это то, что вам нужно ...

Вы можете написать метод, подобный:

protected string getSubObject(object o)
{
    string result = string.empty;

    try
    {
        result = ((subObject)o).Description;
    }
    catch
    { /*Do something here to handle/log your exception*/ } 

    return result;
}

Затем свяжите объект примерно так:

<asp:Literal Text='<%# getSubObject(Eval("Value2")) %>' runat="server" />
...