Преобразовать набор данных в наблюдаемую коллекцию - PullRequest
2 голосов
/ 07 января 2010

Я пытался привязать набор данных к списку. Конечно, потому что я хочу отобразить информацию о нескольких таблицах в табличке данных. Но это кажется невозможным, и мне придется преобразовать его в наблюдаемую коллекцию. Могу ли я сделать это. Мой бл возвращает объекты набора данных. Как я могу преобразовать это в наблюдаемую коллекцию ..? Есть ли способ, чтобы я мог справиться с этой ситуацией в MVVM ..? Как люди обрабатывают наборы данных в архитектуре MVVM ..?

Ответы [ 4 ]

2 голосов
/ 11 мая 2011

Вот как вы можете преобразовать данные в наблюдаемую коллекцию:

  1. Вам необходимо создать класс, который содержит свойства. Каждое свойство представляет столбец в данные. Следовательно, вам нужно установить типы свойств как типы столбцов в таблице данных.
  2. Далее в модели View вы создаете свойство, с которым хотите связать любой элемент управления в xaml. Это свойство будет иметь тип ObservableCollection. Вы можете привязать это свойство к сетке. В случае со списком вы можете сделать ObservableCollection строк и связать его со списком.
  3. Вы можете напрямую заполнить свой результат из БД в коллекции Observable, используя LINQ, или же вы можете вручную добавить элементы в ObservableCollection из таблицы данных.

Нет встроенной функции или преобразования, с помощью которого вы можете преобразовать данные в наблюдаемую коллекцию

2 голосов
/ 07 января 2010

DataSet - это .Net представление набора таблиц и отношений между ними. Это похоже на представление мини-базы данных в коде, доступное в коде. Только несколько элементов управления могут быть привязаны непосредственно к набору данных - те, которые закодированы для анализа связей между таблицами наборов данных и представляют данные различных таблиц в некотором виде иерархического отображения (например, в виде дерева или иерархической сетки). Простой список элементов с одним или двумя свойствами для каждого элемента не может быть связан напрямую с набором данных, он может быть связан только с одним из содержащихся наборов данных.

В качестве альтернативы вам нужно динамически создавать и заполнять собственную таблицу данных, составленную из различных таблиц в наборе данных, который вы используете, чтобы правильно обслуживать определенный элемент управления, с которым вы хотите связать его.

1 голос
/ 05 ноября 2012

Вот код из Datatable в ObservabaleColleaction, как предложил @Hasan Fahim ...

        DataTable dtValues = new DataTable();
        dtValues.Columns.Add("Value1");
        dtValues.Columns.Add("Value2");
        dtValues.Columns.Add("Value3");
        dtValues.Columns.Add("Value4");

        DataRow dr = dtValues.NewRow();
        dr["Value1"] = "asad";
        dr["Value2"] = "naeeem";
        dtValues.Rows.Add(dr);           


 ObservableCollection Values = new ObservableCollection<MyClass>

 (dtValues.AsEnumerable().Select(i => new MyClass
      {

       Value1 = Convert.ToString(i["Value1"]),
       Value2 = Convert.ToString(i["Value2"]),
       Value3 = Convert.ToString(i["Value3"]),
       Value4 = Convert.ToString(i["Value4"])
  }));
0 голосов
/ 05 января 2013

Я все еще работаю над этим, но как насчет этого:

public class cDTObservable<DTType, RowType> : ObservableCollection<RowType>
    where DTType : DataTable
    where RowType : DataRow
{
    private DTType _dt;

    public cDTObservable(DTType dt)
        : base(dt.Rows.OfType<RowType>())
    {
        _dt = dt;
    }

    protected override void ClearItems()
    {
        _dt.Clear();
        base.ClearItems();
    }

    protected override void InsertItem(int index, RowType item)
    {
        if (index > _dt.Rows.Count) throw new ArgumentOutOfRangeException("Argument is out of range");
        if (index == _dt.Rows.Count)
            _dt.Rows.Add(item);
        else
            _dt.Rows.InsertAt(item, index);
        base.InsertItem(index, item);
    }

    protected override void MoveItem(int oldIndex, int newIndex)
    {
        if (oldIndex >= _dt.Rows.Count || newIndex >= _dt.Rows.Count)
            throw new ArgumentOutOfRangeException("Argument is out of range");
        int MyNewIndex = newIndex; //so that I don't override anything that goes to base.MoveItem
        if (oldIndex < newIndex)
            MyNewIndex--;
        RowType dr = (RowType)_dt.Rows[oldIndex];
        _dt.Rows.RemoveAt(oldIndex);
        if (MyNewIndex == _dt.Rows.Count)
            _dt.Rows.Add(dr);
        else
            _dt.Rows.InsertAt(dr, MyNewIndex);
        dr = null;
        base.MoveItem(oldIndex, newIndex);
    }

    protected override void RemoveItem(int index)
    {
        if (index >= _dt.Rows.Count) throw new ArgumentOutOfRangeException("Argument is out of range");
        _dt.Rows[index].Delete(); //Or if you do not need the data to persist in your data store, simply _dt.Rows.RemoveAt(index);
        base.RemoveItem(index);
    }

    protected override void SetItem(int index, RowType item)
    {
        if (index >= _dt.Rows.Count) throw new ArgumentOutOfRangeException("Argument is out of range");
        _dt.Rows.RemoveAt(index);
        if (index > _dt.Rows.Count - 1)
            _dt.Rows.Add(item);
        else
            _dt.Rows.InsertAt(item, index);
        base.SetItem(index, item);
    }
}

Идея состоит в том, что вы наследуете от ObservableCollection и вместо того, чтобы манипулировать копиями данных, вы просто манипулируете ссылками на ваши данные. Таким образом, когда ваша строка обновляется в таблице данных, она будет обновляться и в вашей ObservableCollection (хотя события ObservableCollection не будут запускаться).

Из-за обобщений это также должно работать для Typed DataTables и предоставлять вам доступ к свойствам DataRow (включая DataColumns).

Теоретически это также должно позволить вам использовать ObservableCollection в качестве прокси для вашей таблицы данных для добавления / удаления / изменения содержимого.

Очевидно, так как я все еще работаю над этим для своего проекта, вполне возможно, что я, возможно, пропустил что-то большое, но на данный момент я не понимаю, почему это не сработает (так как я почти уверен, что Rows [Index] .Delete () устанавливает свойство DataRowState вместо фактического удаления объекта DataRow).

...