Bind ItemSource to QueryableCollectionView Disable Add and Remove buttons

6 posts, 0 answers
  1. develuser
    develuser avatar
    14 posts
    Member since:
    Dec 2011

    Posted 05 Jul 2012 Link to this post

    Hi Telerik,

    I have a RadGridView and a RadDataForm both bind to the same collection.

    When I bind the two ItemSource properties to a QueryableCollectionView, the Add and Remove buttons are disabled (as you can see on the attached picture).

    If I bind ItemSource to an ObservableCollection, Add and Remove buttons are enabled but the navigation buttons don't respect the sort specified on the GridView.

    The QueryableCollectionView CanAddNew and CanRemove properties are set to false, but I don't know why.

    How can I do to enable the QueryableCollectionView to add or remove Items ?

    Thank you.

    Greetings,
    Laurent
  2. Ivan Ivanov
    Admin
    Ivan Ivanov avatar
    1128 posts

    Posted 06 Jul 2012 Link to this post

    Hi Laurent,

    I have tried to reproduce such a behavior with the latest version of RadControls, but without any success. I am attaching the test project for your reference. Would you please confirm whether there are any major differences between your approach and mine?

    Greetings,
    Ivan Ivanov
    the Telerik team
    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
  3. DevCraft banner
  4. develuser
    develuser avatar
    14 posts
    Member since:
    Dec 2011

    Posted 06 Jul 2012 Link to this post

    Hi Ivan,

    Thank you for your reply,

    The difference is that I create the collection with a Linq expression (because I use a wrapper around my entity) : 

    public QueryableCollectionView Clubs
    {
        get
        {
            if (this.clubs == null)
            {
     
                this.clubs = new QueryableCollectionView(
                from c in Club.GetClubs() select new SimpleWrapper() { Club = c });
            }
     
            return this.clubs;
        }
    }

    If I use an ObservableCollection as intermediate collection, it works fine in your example. But, in my project, I have an exception  and I do not understand why.

    protected virtual void PopulateView() {
        ObservableCollection<T> myCollection = new ObservableCollection<T>(
            from entity in ServiceAgent.GetEntitySet<TEntity>( false )
            select new T() { Item = entity } );
     
        View = new QueryableCollectionView( myCollection, typeof( T ) );
    }

    PopulateView is call after RIA Services has loaded Data. QueryableCollectionView seems to be in a good state, with CanAddItem and CanRemove set to true and all data in its internal collection. But exception occurs when PropertyChanged event is raised.

    public virtual IEnumerable View {
        get {
            return _view;
        }
        protected set {
            _view = value;
            RaisePropertyChanged( "View" ); // Exception occurs here
        }
    }


    The exception :

            
    {System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: Items collection must be empty before using ItemsSource.
       at Telerik.Windows.Data.DataItemCollection.CheckInternalViewIsNotUsed()
       at Telerik.Windows.Data.DataItemCollection.SetItemsSource(IEnumerable source, Type itemType)
       at Telerik.Windows.Data.DataItemCollection.SetItemsSource(IEnumerable source)
       at Telerik.Windows.Controls.RadDataForm.OnItemsSourcePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
       at Telerik.Windows.PropertyMetadata.PropertyChangeHook.OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
       at System.Windows.DependencyObject.RaisePropertyChangeNotifications(DependencyProperty dp, Object oldValue, Object newValue)
       at System.Windows.DependencyObject.UpdateEffectiveValue(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, ValueOperation operation)
       at System.Windows.DependencyObject.RefreshExpression(DependencyProperty dp)
       at System.Windows.Data.BindingExpression.SendDataToTarget()
       at System.Windows.Data.BindingExpression.SourcePropertyChanged(PropertyPathListener sender, PropertyPathChangedEventArgs args)
       at System.Windows.PropertyPathListener.ReconnectPath()
       at System.Windows.Data.Debugging.BindingBreakPoint.<>c__DisplayClass4.<BreakOnSharedType>b__3()
       --- End of inner exception stack trace ---
       at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
       at System.Delegate.DynamicInvokeImpl(Object[] args)
       at System.Delegate.DynamicInvoke(Object[] args)
       at VisitorManagementViewxaml_7.BindingOperation(Object BindingState, Int32 , Action )}


    If I set View property with my ObservableCollection, everything works except the navigation buttons. 

    I will continue to inversigate, but if you have any idea, or if you have any alternative to synchronize navigation buttons with my gridview, you're welcome.

    Greetings,
    Laurent
  5. develuser
    develuser avatar
    14 posts
    Member since:
    Dec 2011

    Posted 06 Jul 2012 Link to this post

    Hi Ivan,

    I can reproduce the behavior. Just put this line to your dataform :

    CurrentItem="{Binding SelectedItem, ElementName=clubsGrid}"


    I solved my problem by changing the CurrentItem property binding of my dataform. I bind it to the SelectedItem of my ViewModel rather than the SelectedItem of my GridView.

    Old one :

    <telerik:RadGridView x:Name="radGridView" Grid.Row="0" ItemsSource="{Binding View}"
        AutoGenerateColumns="False" SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
        <telerik:RadGridView.Columns>
            ...
        </telerik:RadGridView.Columns>
    </telerik:RadGridView>
    <telerik:RadDataForm x:Name="radDataForm" Grid.Row="1"
        CurrentItem="{Binding SelectedItem, ElementName=radGridView, Mode=TwoWay}"
        AutoGenerateFields="False"
        ItemsSource="{Binding View}"
        Header="{Binding CurrentItem.Item.Guest.NameAndCompany, ElementName=radDataForm}"
        ReadOnlyTemplate="{StaticResource VisitorReadOnlyTemplate}"
        NewItemTemplate="{StaticResource VisitorEditTemplate}"
        EditTemplate="{StaticResource VisitorEditTemplate}"
        AutoEdit="False" AutoCommit="False">
    </telerik:RadDataForm>

    New one :

    <telerik:RadGridView x:Name="radGridView" Grid.Row="0" ItemsSource="{Binding View}"
        AutoGenerateColumns="False" SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
        <telerik:RadGridView.Columns>
            ...
        </telerik:RadGridView.Columns>
    </telerik:RadGridView>
    <telerik:RadDataForm x:Name="radDataForm" Grid.Row="1"
        CurrentItem="{Binding SelectedItem, Mode=TwoWay}"
        AutoGenerateFields="False"
        ItemsSource="{Binding View}"
        Header="{Binding CurrentItem.Item.Guest.NameAndCompany, ElementName=radDataForm}"
        ReadOnlyTemplate="{StaticResource VisitorReadOnlyTemplate}"
        NewItemTemplate="{StaticResource VisitorEditTemplate}"
        EditTemplate="{StaticResource VisitorEditTemplate}"
        AutoEdit="False" AutoCommit="False">
    </telerik:RadDataForm>

    I hope that can help you.

    Greetings,
    Laurent
  6. Ivan Ivanov
    Admin
    Ivan Ivanov avatar
    1128 posts

    Posted 10 Jul 2012 Link to this post

    Hello Laurent,

    Thanks for the clarifications. The LINQ expression that you are using to get the clubs retrieves some IEnumerable that does not define operations like add/remove item (the wrapper type should be irrelevant in this case). As you are aware of the retrieved item-type you can get it is as a generic List, by using .ToList<T>(). I have updated my initial project, in order to demonstrate the difference.

    Greetings,
    Ivan Ivanov
    the Telerik team
    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
  7. develuser
    develuser avatar
    14 posts
    Member since:
    Dec 2011

    Posted 10 Jul 2012 Link to this post

    Tank you Ivan,

    Greetings,
    Laurent
Back to Top
DevCraft banner