Hi,
I want to achive that the nested RadGridView in my RadComboBox gets the focus when the ComboBox' DropDown is opened. For this I want the reference of the nested GridView but ComboBox.FindChildByType<RadGridView> doesn't work.
Here is the XAML Code of my ComboBox
<
telerik:RadComboBox
Name
=
"cbMachineType"
Text
=
"{Binding Fleet}"
Grid.Row
=
"2"
Grid.Column
=
"2"
IsEditable
=
"True"
Width
=
"150"
Height
=
"{Binding ActualHeight, ElementName=txtName}"
DropDownOpened
=
"cbMachineType_DropDownOpened"
>
<
telerik:RadComboBox.Items
>
<
telerik:RadComboBoxItem
>
<
telerik:RadComboBoxItem.Template
>
<
ControlTemplate
>
<
telerik:RadGridView
x:Name
=
"gvMachineType"
ShowGroupPanel
=
"False"
CanUserFreezeColumns
=
"False"
IsReadOnly
=
"True"
IsFilteringAllowed
=
"False"
SelectionMode
=
"Single"
RowIndicatorVisibility
=
"Collapsed"
SelectedItem
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type telerik:RadComboBox}},Path=DataContext.SelectedMachineType}"
DataContext
=
"{StaticResource MachineTypeViewModel}"
ItemsSource
=
"{Binding MachineTypes}"
Width
=
"{Binding Width, ElementName=cbMachineType}"
Height
=
"150"
AutoGenerateColumns
=
"False"
SelectionChanged
=
"gvMachineType_SelectionChanged"
>
<
telerik:RadGridView.Columns
>
<
telerik:GridViewDataColumn
Width
=
"*"
Name
=
"cSubDescription"
Header
=
"Beschreibung"
DataMemberBinding
=
"{Binding Type}"
/>
<
telerik:GridViewDataColumn
Width
=
"1*"
Name
=
"cSubFleet"
Header
=
"Flotte"
DataMemberBinding
=
"{Binding Fleet}"
/>
</
telerik:RadGridView.Columns
>
</
telerik:RadGridView
>
</
ControlTemplate
>
</
telerik:RadComboBoxItem.Template
>
</
telerik:RadComboBoxItem
>
</
telerik:RadComboBox.Items
>
</
telerik:RadComboBox
>
How can I achive this?
Greetings
Alexander
13 Answers, 1 is accepted
The GridView control is placed inside the Popup part of RadComboBox. In order to find it you need first to get the Popup and check inside its children:
private
void
cbMachineType_DropDownOpened(
object
sender, EventArgs e)
{
var comboBox = sender
as
RadComboBox;
if
(comboBox !=
null
)
{
var popup = comboBox.ChildrenOfType<Popup>().FirstOrDefault();
if
(popup !=
null
)
{
var popUpContent = popup.Child
as
FrameworkElement;
if
(popUpContent !=
null
)
{
var gridView = popUpContent.ChildrenOfType<RadGridView>().FirstOrDefault();
if
(gridView !=
null
)
{
//Implement logic here
}
}
}
}
}
Hope this helps.
Regards,
Nasko
Telerik by Progress
From the provided description of the desired behavior you need to focus and select the first row of the GridView as soon as the dropdown part is opened. If that is the case you need to call the Focus method of the GridView and set the SelectedItem property to the desired row:
private
void
cbMachineType_DropDownOpened(
object
sender, EventArgs e)
{
var comboBox = sender
as
RadComboBox;
if
(comboBox !=
null
)
{
var popup = comboBox.ChildrenOfType<Popup>().FirstOrDefault();
if
(popup !=
null
)
{
var popUpContent = popup.Child
as
FrameworkElement;
if
(popUpContent !=
null
)
{
var gridView = popUpContent.ChildrenOfType<RadGridView>().FirstOrDefault();
if
(gridView !=
null
)
{
//Implement logic here
Dispatcher.BeginInvoke(
new
Action(() =>
{
gridView.Focus();
gridView.SelectedItem = ((ObservableCollection<Club>)gridView.ItemsSource).First();
}));
}
}
}
}
}
I hope this will help you.
Regards,
Nasko
Telerik by Progress
We were not able to reproduce the observed by you behavior on our side - when the up/down keys gets pressed the Rows are selected as expected and Popup is not closed.
Please, check the attached sample that demonstrates how the approach works on our side. Try to modify the sample in order to reproduce the observed by you issue and send it back to us - thus we will be able to provide you with a prompt solution.
Hope this helps.
Regards,
Nasko
Telerik by Progress
Some of the events of RadGridView have been handled internally. Because, of that in order to handle to them by yourself you need to use the RegisterClassHandler of the EventManager class. Using that approach you could handle to the MouseLeftButtonDown event and to close a the DropDown part of RadComboBox if selection is performed:
public
MainWindow()
{
InitializeComponent();
this
.DataContext =
new
MyViewModel();
EventManager.RegisterClassHandler(
typeof
(RadGridView), RadGridView.MouseLeftButtonDownEvent,
new
MouseButtonEventHandler(OnMouseLeftButtonDown),
true
);
}
private
void
OnMouseLeftButtonDown(
object
sender, MouseButtonEventArgs e)
{
var gridView = sender
as
RadGridView;
var row = (e.OriginalSource
as
UIElement).ParentOfType<GridViewRow>();
if
(row !=
null
&& gridView !=
null
&& gridView.SelectedItem.Equals(row.Item))
{
if
(
this
.cbMachineType.IsDropDownOpen)
{
this
.cbMachineType.IsDropDownOpen =
false
;
}
}
}
I hope this will help you.
Regards,
Nasko
Telerik by Progress
Works fine, thank you very much!
But one question is left...
For Example:
When the first or the last Item is selected and i press the up or down key with open DropDown the text of the Combobox gets cleared. How can I prevent this?
The observed by you behavior is caused by the internal logic the ComboBox executes when Up/Down keys gets pressed. In order to change that behavior you need to create a custom RadComboBox and override the HandleKeyDown method. So, when the Up/Down keys gets pressed that method should not call its base implementation that executes the default functionality of the control.
Please, check the attached sample that demonstrates the described above approach.
Hope this will help you.
Regards,
Nasko
Telerik by Progress
The behavior you are describing cannot be observed in the sample project that my colleague has provided in his previous update. Please share more details on your setup and the specific scenario when pressing enter selects the last item. Generally, pressing the enter key when RadGridView is not in edit mode would change the selection to the next item. You can check the following article - Custom Keyboard Command Provider - in order to get more information on how to override this behavior.
Regards,
Stefan Nenchev
Telerik by Progress
Hi,
I have taken a look at the CustomKeyboardCommandProvider, here is mine:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.GridView;
namespace DyeingControl
{
class CustomKeyboardCommandProvider : DefaultKeyboardCommandProvider
{
private GridViewDataControl parentGrid;
private DefaultKeyboardCommandProvider defaultKeyboardProvider;
private CustomKeyboardCommandProvider customKeyboardProvider;
public CustomKeyboardCommandProvider(GridViewDataControl grid) : base(grid)
{
this.parentGrid = grid;
}
public override IEnumerable<
ICommand
> ProvideCommandsForKey(Key key)
{
List<
ICommand
> commandsToExecute = base.ProvideCommandsForKey(key).ToList();
if (key == Key.Enter)
{
commandsToExecute.Clear();
commandsToExecute.Add(RadGridViewCommands.SelectCurrentItem);
}
return commandsToExecute;
}
}
}
And here I set it to the RadGridView:
RadGridView gvMachineType =
null
;
private
void
cbMachineType_DropDownOpened(
object
sender, EventArgs e)
{
var comboBox = sender
as
RadComboBox;
if
(comboBox !=
null
)
{
var popup = comboBox.ChildrenOfType<Popup>().FirstOrDefault();
if
(popup !=
null
)
{
var popUpContent = popup.Child
as
FrameworkElement;
if
(popUpContent !=
null
)
{
gvMachineType = popUpContent.ChildrenOfType<RadGridView>().FirstOrDefault();
if
(gvMachineType !=
null
)
{
gvMachineType.KeyboardCommandProvider =
new CustomKeyboardCommandProvider(gvMachineType);
Dispatcher.BeginInvoke(
new
Action(() =>
{
gvMachineType.Focus();
}));
}
}
}
}
}
Is this ok? Or should I do it in another way? When I debug it, the comipler runs through the CustomKeyboardCommandProvider Code and all is ok...but the behavior is still the same...
Please raise a ticket with a sample project so we can have a more detailed look into your specific setup and advise you accordingly.
Regards,
Stefan Nenchev
Telerik by Progress