nikobarli
Topic Author
Posts: 178
Joined: 26 Apr 2017, 06:23

Some limitations of ObservableCollection

13 Sep 2017, 02:56

It seems that there are several limitations of ObservableCollection as follows. Could you please confirm if they are really limitations (or it may be just me couldn't get it right)

1. ObservableCollection doesn't have Count property.

I couldn't bind to the property (e.g. "{Binding ItemList.Count}" failed).

And the documentation is also saying it doesn't have any property.
https://www.noesisengine.com/docs/Gui.C ... ction.html

2. Cannot use simple data structure (e.g. NsString, Drawing::Point) as its item type (types inherited BaseComponent are required).

Thanks.
 
Wanderer
Posts: 168
Joined: 08 May 2017, 18:36

Re: Some limitations of ObservableCollection

13 Sep 2017, 13:14

I am not very experienced, but this is working for me:
class DataModel :  public Noesis::UserControl // Noesis::Core::BaseComponent - this vas previous class, I change it to UserControl, maybe there is better solutions, but I don't know.
{
public:
	DataModel();
	// ... 
	static const Noesis::Gui::DependencyProperty * m_CountValue;
	NsInt32 m_GetCount() const;
	void m_SetCount();
private:
	Noesis::Ptr<Noesis::Gui::ObservableCollection<ContainerItem> > m_Container;
	Noesis::Ptr<ContainerItem> m_ContainerSelectedItem;
	NS_IMPLEMENT_INLINE_REFLECTION(DataModel, Noesis::UserControl) // changed from BaseComponent to UserControl
	{
		NsMeta<Noesis::Core::TypeId>("DataModel");
		NsProp("DataListBoxSourceContainer", &DataModel::m_Container);

		const Noesis::TypeClass* type = Noesis::TypeOf<SelfClass>();
		Noesis::Ptr<Noesis::ResourceKeyType> defaultStyleKey = Noesis::ResourceKeyType::Create(type);
		Noesis::Ptr<Noesis::UIElementData> data = NsMeta<Noesis::UIElementData>(type);
		data->RegisterProperty<NsInt32>(m_CountValue, "COUNT",
			Noesis::FrameworkPropertyMetadata::Create(NsInt32(0), Noesis::FrameworkOptions_None));
	}
	size_t mCount;
};
/// -------------------------------------------------------------------------------------------------------------------
void DataModel::m_func_ContainerAdd()
{
	// ...
	m_SetCount();
}
void DataModel::m_func_ContainerRemove()
{
	// ...
	m_SetCount();
}
// ...
NsInt32 DataModel::m_GetCount() const
{
	return Noesis::DependencyObject::GetValue<NsInt32>(m_CountValue);
}
void DataModel::m_SetCount()
{
	mCount = m_Container->Count();
	Noesis::DependencyObject::SetValue<NsInt32>(m_CountValue, mCount);
}
const Noesis::Gui::DependencyProperty * DataModel::m_CountValue;
In xaml
<TextBlock
				DataContext="{DynamicResource dataModel}"
				Text="{Binding COUNT}"
			/>
Then you see count of your collection.
Btw I tried
<TextBlock
				DataContext="{DynamicResource dataModel}"
				Text="{Binding dataModel.Count, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
			/>
without Noesis::Gui::DependencyProperty * DataModel::m_CountValue in CodeBehind, but it is not working.
 
User avatar
sfernandez
Site Admin
Posts: 1911
Joined: 22 Dec 2011, 19:20

Re: Some limitations of ObservableCollection

14 Sep 2017, 02:01

1. No, ObservableCollection doesn't expose any properties to be bound in the ViewModel. But as you said, it can be exposed via the ViewModel.
2. Simple data must be boxed before added to the observable collection:
Ptr<ObservableCollection<BaseComponent>> collection = *new ObservableCollection<BaseComponent>();
Drawing::Point point(1.0f, 0.0f);
auto boxed = Boxing::Box<Drawing::Point>(point);
collection->Add(boxed.GetPtr());
Some considerations with ViewModel design though:
  • ViewModel doesn't need to be a UserControl or any other UI element class. It is usually a simple BaseComponent.
  • You can bind to properties registered in the reflection, there is no need to create new DependencyProperties.
  • Properties can be read-only if you specify only a Getter for the property.
  • It is better if ViewModel is set via code-behind (viewtopic.php?f=3&t=1166&p=6725#p6725) than explicitely set it in the xaml, because then you are coupling UI with a specific data type.
class DataModel: public BaseComponent, public INotifyPropertyChanged
{
public:
  DataModel(): mItemList(*new ObservableCollection())
  {
    mItemList->CollectionChanged() += MakeDelegate(this, &DataModel::OnItemListChanged);
  }
  
  ObservableCollection<ContainerItem>* GetItemList() const { return mItemList.GetPtr(); }
  NsInt GetItemListCount() const { return mItemList->Count(); }

  PropertyChangedEventHandler& PropertyChanged() { return mPropertyChanged; }

private:
  void OnItemListChanged(BaseComponent* sender, NotifyCollectionChangedEventArgs& e)
  {
    mPropertyChanged(this, PropertyChangedEventArgs(NsSymbol("ItemListCount")));
  }
  
private:
  Ptr<ObservableCollection<ContainerItem>> mItemList;
  PropertyChangedEventHandler mPropertyChanged;
  
  NS_IMPLEMENT_INLINE_REFLECTION(DataModel, BaseComponent)
  {
    NsProp("ItemList", &DataModel::GetItemList);
    NsProp("ItemListCount", &DataModel::GetItemListCount);
  }
};
 
nikobarli
Topic Author
Posts: 178
Joined: 26 Apr 2017, 06:23

Re: Some limitations of ObservableCollection

14 Sep 2017, 03:04

@Wanderer, thanks for your answer. Yes, it is possible to manually expose the property using either DependencyProperty or a simple INPC (INotifyPropertyChanged) Property.

@sfernandez, thanks. I didn't aware that we can use Boxing to put simple data to observable collection. Thanks for the guideline too. Yes, we are pursuing an MVVM approach where the View is decoupled from VM/M.

Anyway, if it is not difficult, I think you should expose the Count property as it is in WPF for future releases.
 
User avatar
sfernandez
Site Admin
Posts: 1911
Joined: 22 Dec 2011, 19:20

Re: Some limitations of ObservableCollection

14 Sep 2017, 16:51

Anyway, if it is not difficult, I think you should expose the Count property as it is in WPF for future releases.
You are right, we just submitted a fix for the next release and Count property will be available to be bound in UI.
 
nikobarli
Topic Author
Posts: 178
Joined: 26 Apr 2017, 06:23

Re: Some limitations of ObservableCollection

15 Sep 2017, 04:16

Great. Thanks !
 
User avatar
jsantos
Site Admin
Posts: 2899
Joined: 20 Jan 2012, 17:18
Contact:

Re: Some limitations of ObservableCollection

18 Sep 2017, 18:28

@sfernandez, thanks. I didn't aware that we can use Boxing to put simple data to observable collection
Anyway, we are aware of this limitation and we are working to improve it in the new type architecture. ObservableCollection should support simple structs, having to use a BaseComponent is quite a memory overhead in many scenarios.
 
nikobarli
Topic Author
Posts: 178
Joined: 26 Apr 2017, 06:23

Re: Some limitations of ObservableCollection

19 Sep 2017, 08:36

Anyway, we are aware of this limitation and we are working to improve it in the new type architecture. ObservableCollection should support simple structs, having to use a BaseComponent is quite a memory overhead in many scenarios.
Yes, since we will extensively used ObservableCollection in our applications, I think that would be great.

Who is online

Users browsing this forum: Google [Bot] and 0 guests