Если вы просто создать ObservableCollection из объединения (как это было предложено в других ответах), ваша коллекция не будет «наблюдаемым.» То есть, изменения в исходных коллекциях не будут распространяться. Чтобы распространять изменения, вам необходимо создать новый класс коллекции, который реализует INotifyCollectionChanged.
В следующем коде я поднимаю действие CollectionChanged с помощью Reset, которое запрашивает у подписчика повторный загрузку всего результата соединения. Это происходит медленнее, но если вам нужны конкретные обновления для каждого элемента, вам необходимо тщательно отследить изменения. Это намного сложнее. В этом случае, вероятно, не нужно использовать LINQ.
public class Customer { public int cid; public int groupid; public string uname; }
public class Group { public int groupid; public string groupname; }
public class CustomerGroup { public string Name { get; set; } public string Groupname { get; set; } }
public class ObservableJoinOfCustomersGroups : IList<CustomerGroup>, INotifyCollectionChanged
{
readonly ObservableCollection<Customer> customers;
readonly ObservableCollection<Group> groups;
List<CustomerGroup> cachedJoin;
public ObservableJoinOfCustomersGroups(ObservableCollection<Customer> customers, ObservableCollection<Group> groups)
{
this.customers = customers;
this.groups = groups;
cachedJoin = doJoin().ToList();
customers.CollectionChanged += (sender, args) =>
{
cachedJoin = doJoin().ToList();
if(CollectionChanged != null)
CollectionChanged.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
};
groups.CollectionChanged += (sender, args) =>
{
cachedJoin = doJoin().ToList();
if(CollectionChanged != null)
CollectionChanged.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
};
}
private IEnumerable<CustomerGroup> doJoin()
{
// Join code here
return customers.Join(groups, p => p.groupid, g => g.groupid, (p, g) => new CustomerGroup{ Name= p.uname, Groupname = g.groupname });
}
public IEnumerator<CustomerGroup> GetEnumerator()
{
return cachedJoin.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(CustomerGroup item)
{
throw new NotSupportedException();
}
public void Clear()
{
throw new NotSupportedException();
}
public bool Contains(CustomerGroup item)
{
return cachedJoin.Contains(item);
}
public void CopyTo(CustomerGroup[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public bool Remove(CustomerGroup item)
{
throw new NotSupportedException();
}
public int Count { get { return cachedJoin.Count(); } }
public bool IsReadOnly { get { return true; } }
public int IndexOf(CustomerGroup item)
{
return cachedJoin.IndexOf(item);
}
public void Insert(int index, CustomerGroup item)
{
throw new NotSupportedException();
}
public void RemoveAt(int index)
{
throw new NotSupportedException();
}
public CustomerGroup this[int index]
{
get { return cachedJoin[index]; }
set { throw new NotSupportedException(); }
}
public event NotifyCollectionChangedEventHandler CollectionChanged;
}