This is a migrated thread and some comments may be shown as answers.

GridViewComboBoxColumn's DataContext problem in a radGridView

6 Answers 360 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Julien
Top achievements
Rank 1
Julien asked on 10 Mar 2011, 04:24 PM
Hi,

I've a problem, I don't know if it's a bug, but it's blocking for me:

I've a Window, which provides some ObservableCollection to my users controls through binding

in my user control, I've a RadGridView which is bound on a property of my code behind. This property use objects issued from the binding with the window.

I've a collection of objects which is displayed.

The problem is:

I'm now trying to add a GridViewComboBoxColumn, but if I put a converter on itemsource only to see which context I've:
<telerik:GridViewComboBoxColumn Header="Channel"  DataMemberBinding="{Binding Channel}" ItemsSource="{Binding  Converter={StaticResource Watcher}}" Width="2*"/>

I get the context of the Window!

Why??? This should be the datacontext of the usercontrol!

I double checked, In my code behind of my code behind, I've never any reference of the window, or somewhere where I could have bound the datacontext to the window?

I've a "theGridName.DataContext = this;" in the userControl's code behind, nothing else.

Thank you for your help

6 Answers, 1 is accepted

Sort by
0
Maya
Telerik team
answered on 11 Mar 2011, 05:17 PM
Hi Julien,

Generally, the DataContext of that specific control should be one the row itself - the corresponding item. However, in order to provide you with a more appropriate solution, I would need a bit more details. What is the exact purpose you want to achieve ? May you provide some relevant code-snippets about your business objects and the way you are setting the grid and the column ? 

Regards,
Maya
the Telerik team
Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
0
Julien
Top achievements
Rank 1
answered on 14 Mar 2011, 07:37 AM
Hi,

The context of the "ItemsSource" cannot be the same current row, because this list cannot be found on the current object

Here is what I got:

<telerik:RadGridView Name="uxRequestGrid" Grid.Row="1"
                                 AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True" CanUserDeleteRows="False" ShowColumnFooters="False"
                                 ShowGroupFooters="False" CanUserInsertRows="False" RowIndicatorVisibility="Collapsed"
                                 ItemsSource="{Binding RequestsToDisplay}" SelectionChanged="CurrentOpenedRequestChanged" ShowGroupPanel="False" RowEditEnded="OnRequestEditEnded">
                <telerik:RadGridView.Columns>
                    <telerik:GridViewDataColumn Header="Id"  DataMemberBinding="{Binding Id}" Width="*" IsReadOnly="True"/>
                    <telerik:GridViewDataColumn Header="Customer"  DataMemberBinding="{Binding CustomerStore.Name}" Width="2*" IsReadOnly="True"/>
                    <telerik:GridViewDataColumn Header="Title"  DataMemberBinding="{Binding Title}" Width="3*"/>
                    <telerik:GridViewComboBoxColumn Header="Product"  Width="2*"  DataMemberBinding="{Binding Product}"  DisplayMemberPath="FullDescription" ItemsSource="{Binding Products}"/>
                    <telerik:GridViewDataColumn Header="Project"  DataMemberBinding="{Binding Project.MainProjectTitle}" IsReadOnly="True" Width="2*"/>
                    <telerik:GridViewDataColumn Header="Creation date"  DataMemberBinding="{Binding BeginDate}" Width="2*" IsReadOnly="True"/>
                </telerik:RadGridView.Columns>
            </telerik:RadGridView>


I'm displaying some "Requests":
public class Request : Base.DataModel
   {
       #region private vars
       private List<Action> _actions;
       private Project _project;
       private DateTime _beginDate;
       private DateTime? _endDate;
       private RequestStatus _status;
       private String _title;
       private int _idProject;
       private Boolean _isNewRequest = false;
       private Product _product;
       private String _bdcProduct;
       #endregion
 
       #region constructor
       /// <summary>
       /// Initializes a new instance of the <see cref="Request"/> class.
       /// </summary>
       public Request()
       {
           Actions = new List<Action>();
           BeginDate = DateTime.Now;
       }
       #endregion
 
       #region public attributes
       /// <summary>
       /// Gets or sets the actions of the intervention.
       /// </summary>
       /// <value>The actions.</value>
       public List<Action> Actions { get { return _actions; } set { _actions = value; NotifyPropertyChanged("Actions"); } }
 
       /// <summary>
       /// Gets or sets the title.
       /// </summary>
       /// <value>The title.</value>
       public String Title { get { return _title; } set { _title = value; NotifyPropertyChanged("Title"); } }
 
       /// <summary>
       /// Gets or sets the project.
       /// </summary>
       /// <value>The project.</value>
       public Project Project { get { return _project; } set { _project = value; NotifyPropertyChanged("Project"); } }
 
       /// <summary>
       /// Creation date time of the intervention
       /// </summary>
       /// <value>The creation date.</value>
       public DateTime BeginDate { get { return _beginDate; } set { _beginDate = value; NotifyPropertyChanged("BeginDate"); } }
 
       /// <summary>
       /// Gets or sets the end date.
       /// </summary>
       /// <value>The end date.</value>
       public DateTime? EndDate { get { return _endDate; } set { _endDate = value; NotifyPropertyChanged("EndDate"); } }
        
       /// <summary>
       /// Gets or sets the status.
       /// </summary>
       /// <value>The status.</value>
       public RequestStatus Status { get { return _status; } set { _status = value; NotifyPropertyChanged("Status"); } }
        
       /// <summary>
       /// Gets or sets the id project.
       /// </summary>
       /// <value>The id project.</value>
       public int IdProject { get { return _idProject; } set { _idProject = value; NotifyPropertyChanged("IdProject"); } }
 
       /// <summary>
       /// Gets or sets the product.
       /// </summary>
       /// <value>The product.</value>
       public Product Product { get { return _product; } set { _product = value; NotifyPropertyChanged("Product"); } }
 
       /// <summary>
       /// Gets or sets the BDC product.
       /// </summary>
       /// <value>The BDC product.</value>
       public String BdcProduct { get { return _bdcProduct; } set { _bdcProduct = value; NotifyPropertyChanged("BdcProduct"); } }
 
       /// <summary>
       /// Gets or sets a value indicating whether this instance is new request.
       /// </summary>
       /// <value>
       ///     <c>true</c> if this instance is new request; otherwise, <c>false</c>.
       /// </value>
       public Boolean IsNewRequest { get { return _isNewRequest; } set { _isNewRequest = value;NotifyPropertyChanged("IsNewRequest"); } }
       #endregion
 
       #region Overrides of DataModel
 
       /// <summary>
       /// Imports the values.
       /// </summary>
       /// <param name="newObject">The new object.</param>
       public override void ImportValues(Base.DataModel newObject)
       {
           Request  request= newObject as Request;
           if(request!=null)
           {
               Id = request.Id;
               Title = request.Title;
               BeginDate = request.BeginDate;
               EndDate = request.EndDate;
               Status = request.Status;
               IdProject = request.IdProject;
           }
       }
 
       #endregion
   }



In the constructor of the code behind of my user control, I've:
uxRequestGrid.DataContext = this;

Here is how I declare the binding of my Requests in the usercontrol:
#region Requests
 
 
        /// <summary>
        ///
        /// </summary>
        public static readonly DependencyProperty RequestsProperty = DependencyProperty.Register(RequestsPropertyName,
                                                                                                  typeof(List<Request>),
                                                                                                  typeof(RequestsView),
                                                                                                  new UIPropertyMetadata(null, OnRequestsChanged));
 
 
        /// <summary>
        /// Gets or sets the requests.
        /// </summary>
        /// <value>The requests.</value>
        public List<Request> Requests { get { return (List<Request>)GetValue(RequestsProperty); } set { SetValue(RequestsProperty, value); } }
 
 
        /// <summary>
        /// Called when [requests changed].
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="args">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
        private static void OnRequestsChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
        {
            RequestsView view = (RequestsView)property;
            view.OnRequestsChanged((List<Request>)args.NewValue);
        }
 
        /// <summary>
        /// Called when [requests changed].
        /// </summary>
        /// <param name="newValue">The new value.</param>
        protected void OnRequestsChanged(List<Request> newValue)
        {
 
            if (newValue == null)
            {
                RequestsToDisplay = null;
                uxRequestGrid.SelectedItem = null;
            }
            else
            {
                RequestsToDisplay = new ObservableCollection<Request>(Requests.Where(r => r.Status == DataToDisplay).ToList());
                uxRequestGrid.SelectedItem = RequestsToDisplay.FirstOrDefault();
            }
            NotifyPropertyChanged("RequestsToDisplay");
            NotifyPropertyChanged(RequestsPropertyName);
 
        }
 
        #endregion
(I've to display only a subset of requests, it's why I'm not directly bound to the "Requests" property)

Products are bound with the same way:
#region Products
 
 
/// <summary>
///
/// </summary>
public static readonly DependencyProperty ProductsProperty = DependencyProperty.Register(ProductsPropertyName,
                                                                                          typeof(List<Product>),
                                                                                          typeof(RequestsView),
                                                                                          new UIPropertyMetadata(null, OnProductsChanged));
 
 
/// <summary>
/// Gets or sets the requests.
/// </summary>
/// <value>The requests.</value>
[Category("Infoteam Properties"), Browsable(true), DefaultValue(null)]
public List<Product> Products { get { return (List<Product>)GetValue(ProductsProperty); } set { SetValue(ProductsProperty, value); } }
 
 
/// <summary>
/// Called when [requests changed].
/// </summary>
/// <param name="property">The property.</param>
/// <param name="args">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
private static void OnProductsChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
{
    RequestsView view = (RequestsView)property;
    view.OnProductsChanged((List<Product>)args.NewValue);
}
 
/// <summary>
/// Called when [requests changed].
/// </summary>
/// <param name="newValue">The new value.</param>
protected void OnProductsChanged(List<Product> newValue)
{
    NotifyPropertyChanged(ProductsPropertyName);
}
 
#endregion


Request are correctly loaded, with the right datacontext, but "Products" cannot be found:
System.Windows.Data Error: 40 : BindingExpression path error: 'Products' property not found on 'object' ''MainWindow' (Name='')'. BindingExpression:Path=Products; DataItem='MainWindow' (Name=''); target element is 'RequestsView' (Name=''); target property is 'Products' (type 'List`1')

(MainWindow is the view which contains my user controls)

How is it possible that ItemSource of the grid is correct, but ItemsSource of the RadGridViewComboBox, which I can't change the context, has the window which contains the user control as datacontext.

Thank you
0
Maya
Telerik team
answered on 17 Mar 2011, 01:22 PM
Hello Julien,

In order to provide you with an appropriate solution, I would need just a little more details. May you clarify where is the Products defined - is it a property of a particular class ? 

Best wishes,
Maya
the Telerik team
0
Julien
Top achievements
Rank 1
answered on 17 Mar 2011, 01:38 PM
Hi,

Actually, Products is declared as a property of the UserControl component code behind.

And what I don't understand, it's how it is possible that the datacontext is the mainWindow here(and it's really, if I create a property named "Products" on the main windows, I don't have this error anymore and I see products).

Here is how it's defined:
#region Products
 
public static readonly DependencyProperty ProductsProperty = DependencyProperty.Register(ProductsPropertyName,
                                                                                          typeof(List<Product>),
                                                                                          typeof(RequestsView),
                                                                                          new UIPropertyMetadata(null, OnProductsChanged));
 
 
 
public List<Product> Products{ get { return (List<Request>)GetValue(ProductsProperty); } set { SetValue(ProductsProperty, value); } }
 
private static void OnProductsChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
{
    RequestsView view = (RequestsView)property;
    view.OnProductsChanged((List<Product>)args.NewValue);
}
 
protected void OnProductsChanged(List<Product> newValue)
{
 
    NotifyPropertyChanged(ProductsPropertyName);
 
}
 
#endregion
0
Pavel Pavlov
Telerik team
answered on 22 Mar 2011, 04:58 PM
Hi Julien,

The DataContext inside the user control would be inherited form the window, unless you take care to set it .  For example when initializing the user control you may do something like :
this.DataContext = this.

I believe this is an expected WPF behavior.

Kind regards,
Pavel Pavlov
the Telerik team
0
Julien
Top achievements
Rank 1
answered on 23 Mar 2011, 08:24 AM
I've done this: I've a Grid, which contains all other components of my userControl, and I've done:

uxMainGrid.DataContext = this; in the constructor, after the InitializeComponents();
Tags
GridView
Asked by
Julien
Top achievements
Rank 1
Answers by
Maya
Telerik team
Julien
Top achievements
Rank 1
Pavel Pavlov
Telerik team
Share this question
or