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

Tab in and Click on DropDown Button which is made the Custom Drop Down

5 Answers 69 Views
Buttons
This is a migrated thread and some comments may be shown as answers.
Syed Danish
Top achievements
Rank 1
Syed Danish asked on 28 May 2010, 11:04 AM
Hi,

I am using the rad drop down button and made a custom control out of it. This control gives me a peculier problem, the drop down button in its popup opens the grid control. I also made the control with the arrow keys to work on tab out but the problem is that if the arrow key is made to work and again if the user needs to click on the rad drop down button this throws an error. I tried to override the OnClick event but that was of no use and gave me the same error. The error message is "Error HRESULT E_FAIL has been returned from a call to a COM component." Please help me, thanks in advance.

Thanks and Regards,
Syed Danish

5 Answers, 1 is accepted

Sort by
0
Bobi
Telerik team
answered on 02 Jun 2010, 01:11 PM
Hello Syed Danish,

We are unable to reproduce this issue. Is is possible to send us some sample code or explain in more details the structure of your application?

Best wishes,
Bobi
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Syed Danish
Top achievements
Rank 1
answered on 25 Jun 2010, 01:11 PM
using System;  
using System.Net;  
using System.Windows;  
using System.Windows.Controls;  
using System.Windows.Documents;  
using System.Windows.Ink;  
using System.Windows.Input;  
using System.Windows.Media;  
using System.Windows.Media.Animation;  
using System.Windows.Shapes;  
using Telerik.Windows.Controls;  
using System.Linq;  
using System.ComponentModel;  
using System.Collections;  
using System.Collections.Generic;  
using System.Reflection;  
 
namespace Controlkit.Module  
{  
    [Description("This is a Custom Dropdown Control with a Grid")]  
    public class CustomDropdown : RadDropDownButton  
    {  
        protected TextBlock lblContent;  
        protected DataGrid grid;  
        protected int itemCount;  
 
 
        public CustomDropdown()  
            : base()  
        {  
            this.lblContent = new TextBlock();  
            this.lblContent.Padding = new Thickness(10, 0, 0, 0);  
            this.HorizontalContentAlignment = HorizontalAlignment.Left;  
            this.Content = this.lblContent;  
 
            //now the grid              
            this.grid = new DataGrid();  
            this.grid.HeadersVisibility = DataGridHeadersVisibility.Column;  
            this.grid.IsReadOnly = true;  
            this.grid.SelectionMode = DataGridSelectionMode.Single;  
            this.grid.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;  
 
 
            this.grid.SelectionChanged += new System.Windows.Controls.SelectionChangedEventHandler(grid_SelectionChanged);  
            this.grid.LayoutUpdated += new EventHandler(grid_LayoutUpdated);  
            //this.grid.GridLinesVisibility = DataGridGridLinesVisibility.None;  
            SolidColorBrush grdBack = new SolidColorBrush(Colors.Transparent);  
            this.grid.RowBackground = grdBack;  
            this.grid.AlternatingRowBackground = grdBack;  
            this.DropDownContent = this.grid;  
 
            this.Height = 25;  
            this.itemCount = 0;  
        }  
 
        protected override void OnKeyDown(KeyEventArgs e)  
        {  
            //base.OnKeyDown(e);  
            switch (e.Key)  
            {  
                case Key.Down:  
                    if (this.grid.SelectedIndex < this.itemCount) this.grid.SelectedIndex++;  
                    break;  
                case Key.Up:  
                    if (this.grid.SelectedIndex > -1) this.grid.SelectedIndex--;  
                    break;  
            }  
        }  
 
        void grid_LayoutUpdated(object sender, EventArgs e)  
        {  
            double width = 15;  
            foreach (var col in this.grid.Columns)  
            {  
                width += col.ActualWidth;  
            }  
            this.grid.Width = (width > this.MinWidth) ? width : this.MinWidth;  
            if (grid.ItemsSource != null)  
            {  
                double height = 12;  
                foreach (var item in grid.ItemsSource)  
                {  
                    height += 25;  
                    if (height > 160) break;  
                }  
                grid.Height = height;  
            }  
        }  
 
        /// <summary>  
        /// This is the event handler for grids selection change.   
        /// </summary>  
        /// <param name="sender"></param>  
        /// <param name="e"></param>  
        void grid_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)  
        {  
            if (e.AddedItems.Count > 0)  
            {  
                this.lblContent.DataContext = e.AddedItems[0];  
                _selection = e.AddedItems[0];  
                SelectedValue = GetMemberValue(_selection);  
            }  
            else 
            {  
                _selection = null;  
                SelectedValue = null;  
            }  
            this.OnSelectionChanged(e);  
            this.IsOpen = false;  
        }  
 
        /// <summary>  
        /// for implementing the onevent pattern  
        /// </summary>  
        /// <param name="e"></param>  
        protected virtual void OnSelectionChanged(System.Windows.Controls.SelectionChangedEventArgs e)  
        {  
            if (this.SelectionChanged != null)  
            {  
                this.SelectionChanged(this, e);  
            }  
        }  
        /// <summary>  
        /// The text property. It returns the text of the   
        /// current combobox selection  
        /// </summary>  
        public string Text  
        {  
            get 
            {  
                return this.lblContent.Text;  
            }  
            set 
            {  
                this.lblContent.Text = value;  
            }  
        }  
 
 
        public static DependencyProperty GridHeightProperty =  
          DependencyProperty.Register("GridHeight"typeof(double), typeof(PhoenixCustomDropdown), new PropertyMetadata(  
              (o, e) =>  
              {  
                  ((PhoenixCustomDropdown)o).grid.Height = (double)e.NewValue;  
              }  
              ));  
 
        /// <summary>  
        /// The height of the grid  
        /// </summary>  
        public double GridHeight  
        {  
            get 
            {  
                return (double)GetValue(GridHeightProperty);  
            }  
            set 
            {  
                SetValue(GridHeightProperty, value);  
            }  
        }  
 
        public static DependencyProperty ItemsSourceProperty =  
          DependencyProperty.Register("ItemsSource"typeof(IEnumerable), typeof(PhoenixCustomDropdown), new PropertyMetadata(  
              (o, e) =>  
              {  
                  PhoenixCustomDropdown cdd = (PhoenixCustomDropdown)o;  
                  IList lst = (IList)e.NewValue;  
                  cdd.itemCount = lst.Count;  
                  if (cdd.DefaultValueText != null)  
                  {  
                      var first = lst[0];  
                      var blank = Activator.CreateInstance(first.GetType());  
                      blank.GetType().GetProperty(cdd.DisplayMemberPath).SetValue(blank, cdd.DefaultValueText, null);  
                      //blank.GetType().GetProperty(cdd.ValueMemberPath).SetValue(blank, null, null);  
 
                      List<object> result = new List<object>();  
                      result.Add(blank);  
                      result.AddRange(lst);  
                      cdd.grid.ItemsSource = result;  
                      if (cdd.SelectedValue == null) cdd.SelectedValue = blank.GetType().GetProperty(cdd.ValueMemberPath).GetValue(blank, null);  
                  }  
                  else 
                  {  
                      cdd.grid.ItemsSource = lst;  
                  }  
                  if (cdd.DefaultDisplayColumn != null)  
                  {  
                      var deflt = (  
                          from object itm in cdd.grid.ItemsSource  
                          where (bool)itm.GetType().GetProperty(cdd.DefaultDisplayColumn).GetValue(itm, null)  
                          select itm  
                                   ).FirstOrDefault();  
                      if (deflt != null)  
                      {  
                          if (cdd.SelectedValue == null) cdd.SelectedValue = deflt.GetType().GetProperty(cdd.ValueMemberPath).GetValue(deflt, null);  
                      }  
                  }  
                  cdd.SetSelectionFromValue();  
              }  
              ));  
 
        /// <summary>  
        /// The items source to be used for displaying the items in the grid  
        /// </summary>  
        public IEnumerable ItemsSource  
        {  
            get 
            {  
                return this.grid.ItemsSource;  
            }  
            set 
            {  
                SetValue(ItemsSourceProperty, value);  
            }  
        }  
 
        public static DependencyProperty SelectedItemProperty =  
          DependencyProperty.Register("SelectedItem"typeof(object), typeof(PhoenixCustomDropdown), new PropertyMetadata(  
              (o, e) =>  
              {  
 
              }  
              ));  
 
        /// <summary>  
        /// This property gives the selected item  
        /// </summary>  
        [Description("This will return a single selected item from the items source")]  
        public object SelectedItem  
        {  
            get 
            {  
                return ((object)(GetValue(PhoenixCustomDropdown.SelectedItemProperty)));  
            }  
            set 
            {  
                SetValue(PhoenixCustomDropdown.SelectedItemProperty, value);  
            }  
        }  
 
 
        public static DependencyProperty DisplayMemberPathProperty =  
          DependencyProperty.Register("DisplayMemberPath"typeof(string), typeof(PhoenixCustomDropdown), null);  
 
        /// <summary>  
        /// Here you can set column name of the grid to be displayed in the selected textbox  
        /// </summary>  
        public string DisplayMemberPath  
        {  
            get 
            {  
                return ((string)(base.GetValue(PhoenixCustomDropdown.DisplayMemberPathProperty)));  
            }  
            set 
            {  
                base.SetValue(PhoenixCustomDropdown.DisplayMemberPathProperty, value);  
                this.lblContent.SetBinding(TextBlock.TextProperty, new System.Windows.Data.Binding() { Source = this.lblContent.DataContext, Path = new PropertyPath(value) });  
            }  
        }
        #region copied code  
 
        private object _selection;  
 
        /// <summary>  
        /// Returns the value from a particular record  
        /// </summary>  
        /// <param name="item">The single record to evaluate</param>  
        /// <returns>The value memeber value</returns>  
        private object GetMemberValue(object item)  
        {  
            return item.GetType().GetProperty(ValueMemberPath).GetValue(item, null);  
        }  
 
        private object GetMemberDisplay(object item)  
        {  
            try 
            {  
                return item.GetType().GetProperty(DisplayMemberPath).GetValue(item, null);  
            }  
            catch (Exception)  
            {  
                return null;  
            }  
        }  
 
 
 
        public static DependencyProperty ValueMemberPathProperty =  
          DependencyProperty.Register("ValueMemberPath"typeof(string), typeof(PhoenixCustomDropdown), null);  
 
        /// <summary>  
        /// The name of the colum whos value will be returned while a single item is selected  
        /// </summary>  
        public string ValueMemberPath  
        {  
            get 
            {  
                return ((string)(base.GetValue(PhoenixCustomDropdown.ValueMemberPathProperty)));  
            }  
            set 
            {  
                base.SetValue(PhoenixCustomDropdown.ValueMemberPathProperty, value);  
            }  
        }  
 
        public static DependencyProperty SelectedValueProperty =  
          DependencyProperty.Register("SelectedValue"typeof(object), typeof(PhoenixCustomDropdown),  
          new PropertyMetadata((o, e) =>  
          {  
              ((PhoenixCustomDropdown)o).SetSelectionFromValue();  
          }));  
 
        /// <summary>  
        /// The selected value,based on the selection  
        /// </summary>  
        public object SelectedValue  
        {  
            get 
            {  
                return ((object)(base.GetValue(PhoenixCustomDropdown.SelectedValueProperty)));  
            }  
            set 
            {  
                base.SetValue(PhoenixCustomDropdown.SelectedValueProperty, value);  
            }  
        }  
 
        private void SetSelectionFromValue()  
        {  
            var value = SelectedValue;  
            if (ItemsSource != null && value != null)  
            {  
                var sel = (from object item in ItemsSource  
                           where GetMemberValue(item).Equals(value)  
                           select item).Single();  
                _selection = sel;  
                SelectedItem = sel;  
                this.lblContent.Text = this.GetMemberDisplay(sel).ToString();  
            }  
        }
        #endregion  
 
        [Description("Please do handle this event in case you want to do something specific while the selection of the combobox is changed")]  
        public event System.Windows.Controls.SelectionChangedEventHandler SelectionChanged;  
 
        protected string _cols;  
        /// <summary>  
        /// This is where we are going to pass the columns  
        /// The format should be col1,col2,col3 etc.  
        /// </summary>  
        public string Columns  
        {  
            set 
            {  
                this._cols = value;  
 
                this.grid.AutoGenerateColumns = false;  
 
                foreach (string col in value.Split(','))  
                {  
                    string[] vals = col.Split('|');  
                    DataGridTextColumn dtcol = new DataGridTextColumn();  
                    dtcol.Binding = new System.Windows.Data.Binding(vals[0]);  
                    dtcol.Width = DataGridLength.SizeToCells;  
                    dtcol.Header = (vals.Length > 1 ? vals[1] : vals[0]);  
                    this.grid.Columns.Add(dtcol);  
                }  
                if (grid.Columns.Count == 1)  
                {  
                    this.grid.HeadersVisibility = DataGridHeadersVisibility.None;  
                    this.grid.GridLinesVisibility = DataGridGridLinesVisibility.None;  
                }  
            }  
            get 
            {  
                return this._cols;  
            }  
        }  
 
        /// <summary>  
        /// This is the text which is going to come when there   
        /// is no other values added to it.   
        /// for example it will display none if you select nothing.  
        /// </summary>  
        [Description("Add the default value text which will be displayed by default in case there is no data selected")]  
        public string DefaultValueText  
        {  
            get;  
            set;  
        }  
 
        [Description("Here you can add the default display column name which will be used for selecting the default value")]  
        public string DefaultDisplayColumn  
        {  
            set;  
            get;  
        }  
    }  
}  
 
The above is the code for the custom drop down which i made. The drop down content here is the Data Grid. I need the arrow keys in this to work, this works fine but when the user tabs in to the control and accesses the arrow keys and again if the user wants to use his mouse to work on the same control this gives an error "Error HRESULT E_FAIL has been returned from a call to a COM component."
 The XAML line for this control is some thing like this.
        <Kit:CustomDropdown x:Name="cmbDepartment" Grid.Row="1" Grid.Column="4" Style="{StaticResource ComboStyle}" HorizontalAlignment="Left" Margin="6,6,6,6" Width="Auto" ItemsSource="{Binding Source={StaticResource GetOrganisationDepartmentList}, Path=Data}" Columns="Code" DisplayMemberPath="Code" ValueMemberPath="Code" DefaultDisplayColumn="DefaultDisplay" DefaultValueText="Select"/>  

Please help me out.

Thanks and Regards,
Syed Danish
0
Miro Miroslavov
Telerik team
answered on 30 Jun 2010, 12:36 PM
Hello Syed Danish,

As far as I see, the problem could be in the LayoutUpdated event handler. Because in the handler, there is code that will rise the event again and again - this will end in recursive Layout updates. And the selection from the other hand could cause the Layou pass, which will call the handler.
I strongly suggest you not to use the LayoutUpdated event for such a scenarios.
But to make sure what causes the problem, it will be better if we can debug it, so if you can send us the example project?
Thank you.

Sincerely yours,
Miro Miroslavov
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Syed Danish
Top achievements
Rank 1
answered on 01 Jul 2010, 01:37 PM
Hi Miro Miroslavov,
This dosent really helped me. Can you tell me how to upload the project so that I can show you the exact behaviour of the custom control.
0
Miro Miroslavov
Telerik team
answered on 02 Jul 2010, 03:34 PM
Hi Syed Danish,

You have to create a new support ticket and you will see the option to attach file.

Regards,
Miro Miroslavov
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
Buttons
Asked by
Syed Danish
Top achievements
Rank 1
Answers by
Bobi
Telerik team
Syed Danish
Top achievements
Rank 1
Miro Miroslavov
Telerik team
Share this question
or