Usercontrol and Dynamic Tabitems MVVM

4 posts, 0 answers
  1. palak
    palak avatar
    102 posts
    Member since:
    May 2011

    Posted 29 Oct 2012 Link to this post

    Hello Team,

    I've checked latest [Binding] demo which dynamic tabitems in your demo site. It only shows binding to custom viewmodel as tabitem. No content property in that viewmodel what if i want to set custom control, usercontrol as it's content dynamically.

    Actually what i am trying to achieve is as below :
    - Navigation page - should contain radtabcontrol which binds via itemsource property
    - Navigation page viewmodel - contains observablecollecation of tabitems

    - UserControl 1 - list of UI elementes , bound with properties defined in UserControl 1 Viewmodel
    - UserControl 2 -  list of UI elementes , bound with properties defined in UserControl 2 Viewmodel
    - UserControl 3 - list of UI elementes , bound with properties defined in UserControl 3 Viewmodel

    - Commands in UserControl 1 initiate event, & new dynamic tabitem should be added to Navigation Page Viewmodel.
    In this newely dynamic tabitem, how can i set UserControl 2 as it's content.

    My point is, i want to assign my UserControls to dynamic radtabitems, and also want to generate tabitems dynamically.

    UserControls & their Viewmodels should be working as it works in MVVM.

    Functionalities are like GridView with [List/Edit] operations & want to do it on dynamic radtabitems, and those radtabitems should be hold my UserControls whatever it is.

    Kindly help.

    Thanks
    palak

  2. Pavel R. Pavlov
    Admin
    Pavel R. Pavlov avatar
    1183 posts

    Posted 01 Nov 2012 Link to this post

    Hi Palak,

    Let me first make a quick clarification - it is considered a bad practice to have visual objects in the ViewModel. This is why I'd suggest an approach where the UserControls are used as ContentTemplates for the RadTabControl.

    You can start with creating an ItemViewModel class with property (e.g Content) of type object which will hold the DataContext of the content of the RadTabItems (in your case the UserControl ViewModels). After that you can use the RadTabControl.ContentTemplateSelector property to select the corresponding template for the Content of the TabItems (e.g UserControl1, UserControl2...) based on your custom logic.

    In order to add new TabItems dynamically you can define a DelegateCommand property in the UserControl1/2/3 ViewModels. The execute method of the command can be implemented in the MainViewModel where the collection of tabs should be defined as well. You can examine a similar approach for adding/removing tabs through DelegateCommands in this demo solution.

    I also prepared a sample solution to demonstrate the above suggestions. Take a look at it and tell me if it fits your needs.

    All the best,
    Pavel R. Pavlov
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  3. DevCraft banner
  4. palak
    palak avatar
    102 posts
    Member since:
    May 2011

    Posted 06 Nov 2012 Link to this post

    Hello Pavel,

    I am very thankful for the reference project & sample implementation.

    Actually my problem is, i am trying to open an [Edit] tab on click of [radbutton] which is part of radgridview column celltemplate.
    [AddNewTab] delegate command is not going to fire in this case. but if i bind this command somewhere else in zammel, then it gets fired perfectly.
    Here is the sample code, for your reference.

    ZAMMEL :
    <telerik:RadGridView x:Name="grdProjects"
                                         Grid.Row="0"
                                         AlternationCount="2"
                                         AutoGenerateColumns="False"
                                         CanUserFreezeColumns="False"
                                         ColumnWidth="Auto"
                                         helpers:CustomFilterBehavior.TextBox="{Binding ElementName=txtSearch}"
                                         IsReadOnly="True"
                                         ItemsSource="{Binding GetProjectsDetails}"
                                         RowIndicatorVisibility="Collapsed"
                                         ScrollViewer.VerticalScrollBarVisibility="Disabled"
                                         ShowGroupPanel="False">
                        <telerik:RadGridView.Columns>
                            <telerik:GridViewColumn>
                                <telerik:GridViewColumn.CellTemplate>
                                    <DataTemplate>
                                        <telerik:RadButton Command="{Binding AddNewTab}" CommandParameter="{Binding Title}">
                                            <Grid Background="{StaticResource SCBMisBlue}">
                                                <Image Width="24"
                                                       Height="24"
                                                       Source="/Radix.MIS.App;component/Assets/Images/edit.png" />
                                            </Grid>
                                        </telerik:RadButton>
     
                                    </DataTemplate>
                                </telerik:GridViewColumn.CellTemplate>
                            </telerik:GridViewColumn>
     
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding CmpId}" Header="CmpId" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding OpportunityId}" Header="OpportunityId" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding ProjectCode}" Header="Project Code" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding ProjectName}" Header="Project Name" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding Description}" Header="Description" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding ProjectCost}" Header="Project Cost" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding BillingModelId}" Header="BillingModel Id" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding DepartmentId}" Header="DepartmentId" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding ProjectManager}" Header="ProjectManager" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding KeyResponsible}" Header="KeyResponsible" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding BusinessClosedDate}" Header="Business Closed Date" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding ProjectStartDate}" Header="Project Start Date" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding PlannedEndDate}" Header="Planned End Date" />
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding ActualEndDate}" Header="Actual End Date" />
     
                        </telerik:RadGridView.Columns>
                    </telerik:RadGridView>

    MainPage.xaml
    <UserControl.Resources>
     
           <DataTemplate x:Key="UserControl1">
               <viewp:ProjectList />
           </DataTemplate>
           <DataTemplate x:Key="UserControl2">
               <viewp:ProjectDetails />
           </DataTemplate>
           <DataTemplate x:Key="UserControl3">
               <viewm:MilestoneList />
           </DataTemplate>
           <DataTemplate x:Key="UserControl4">
               <viewm:MilestoneDetails />
           </DataTemplate>
           <helper:MyTemplateSelector x:Key="MyTemplateSelector"
                                      UserControl1="{StaticResource UserControl1}"
                                      UserControl2="{StaticResource UserControl2}"
                                      UserControl3="{StaticResource UserControl3}"
                                      UserControl4="{StaticResource UserControl4}" />
           <DataTemplate x:Key="HeaderTemplate">
               <TextBlock Text="{Binding Header}" />
           </DataTemplate>
       </UserControl.Resources>
       <Grid x:Name="LayoutRoot" Background="White">
           <telerik:RadTabControl x:Name="xTabControl"
                                  Grid.Row="0"
                                  ContentTemplateSelector="{StaticResource MyTemplateSelector}"
                                  ItemsSource="{Binding Items}"
                                  ItemTemplate="{StaticResource HeaderTemplate}">
               <telerik:RadTabControl.ItemContainerStyle>
                   <Style TargetType="telerik:RadTabItem">
                       <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                   </Style>
               </telerik:RadTabControl.ItemContainerStyle>
           </telerik:RadTabControl>
       </Grid>

    MainViewModel
    public class MainViewModel
        {
        public ObservableCollection<ItemViewModel> Items { get; set; }
        public MainViewModel()
            {
     
            this.Items = new ObservableCollection<ItemViewModel>();
            this.Items.Add(new ItemViewModel()
            {
                Header = "Tab 1",
                Content = new ProjectListVM()
                {
                    AddNewTab = new DelegateCommand(this.AddTab),
                    Title = "UserControl 1"
                },
                IsSelected = true
            });
            }
        protected void AddTab(object param)
            {
            switch (param.ToString())
                {
                case "UserControl 1":
                    this.Items.Add(new ItemViewModel()
                    {
                        Header = "UC2",
                        Content = new ProjectDetailsVM()
                        {
                            AddNewTab = new DelegateCommand(this.AddTab),
                            Title = "UserControl 2"
                        },
                        IsSelected = true
                    });
                    break;
                case "UserControl 2":
                    this.Items.Add(new ItemViewModel()
                    {
                        Header = "UC3",
                        Content = new MilestoneListVM()
                        {
                            AddNewTab = new DelegateCommand(this.AddTab),
                            Title = "UserControl 3"
                        },
                        IsSelected = true
                    });
                    break;
                case "UserControl 3":
                    this.Items.Add(new ItemViewModel()
                    {
                        Header = "UC1",
                        Content = new MilestoneDetailsVM()
                        {
                            AddNewTab = new DelegateCommand(this.AddTab)
                        },
                        IsSelected = true
                    });
                    break;
                default:
                    this.Items.Add(new ItemViewModel()
                    {
                        Header = "UC2",
                        Content = new ProjectListVM()
                        {
                            AddNewTab = new DelegateCommand(this.AddTab),
                            Title = "UserControl 2"
                        },
                        IsSelected = true
                    });
                    break;
                }
     
            }
        }


    ProjectListVM.cs
    public DelegateCommand AddNewTab
             {
             get;
             set;
             }
     
         public string Title { get; set; }


    Can you please tell me what i am missing here.

    Thanks,
    palak


  5. Pavel R. Pavlov
    Admin
    Pavel R. Pavlov avatar
    1183 posts

    Posted 08 Nov 2012 Link to this post

    Hello Palak,

    As far as I understand you want to execute a delegate command when you press a RadButton placed in a RadGridView cell.

    Let me make a quick clarification. When RadButton.Command property is bound to a command business property, you need to make sure that the business property is defined in the DataContext of the RadButton. Otherwise the binding won't be able to apply any command to the Button.Command property.

    In your case as you put the RadButton inside RadGridView cells, you have to define the delegate command (along with it's Execute and CanExecute methods) in the class describing the items in the RadGridView.ItemsSource.

    If this approach is not working for you or you have any other questions it will be best if you send me your project or modify the project previously sent by me, so that it demonstrates your approach and issues.

    All the best,
    Pavel R. Pavlov
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Back to Top