Hi...
I would like to inherit from the RadComboBox to have a NullableComboBox which allows us to set a distinct template for anull value within the combobox declaration.
Something like this
The Null value is inserted in the list using a quite simple converter as I don't want my ViewModel to expose a list with a null value.
I'm able to display the templated item. This works fine. Unfortunatly, I'm just not able to get the SelectionChanged event to be raised when I select it. I was able to do this stuff using a regular ComboBox and I noticed that the PrepareContainerForItemOverride method is raised earlier in the comboxBox than in the RadComboBox (which is raised only when the user clicks on the combobox).
I'm requesting some help, I would greatly appreciate to benefit from the rich feature set of the radcombobox.
Here's the code for the custom control
Thanks!
I would like to inherit from the RadComboBox to have a NullableComboBox which allows us to set a distinct template for anull value within the combobox declaration.
Something like this
<CustomControls:RadCustomComboBox |
ItemsSource="{Binding SomeEntities, Converter={StaticResource nullableItemSourceConverter}}"> |
<CustomControls:RadCustomComboBox.NullValueContentTemplate> |
<DataTemplate> |
<TextBlock Text="Something representing a null value" /> |
</DataTemplate> |
</CustomControls:RadCustomComboBox.NullValueContentTemplate> |
<CustomControls:RadCustomComboBox.ItemTemplate> |
<DataTemplate> |
<StackPanel Orientation="Horizontal"> |
<TextBlock Text="{Binding Path=Attribute1}" /> |
<TextBlock Text="{Binding Path=Attribute2}" Foreground="DarkRed" /> |
</StackPanel> |
</DataTemplate> |
</CustomControls:RadCustomComboBox.ItemTemplate> |
</CustomControls:RadCustomComboBox> |
The Null value is inserted in the list using a quite simple converter as I don't want my ViewModel to expose a list with a null value.
I'm able to display the templated item. This works fine. Unfortunatly, I'm just not able to get the SelectionChanged event to be raised when I select it. I was able to do this stuff using a regular ComboBox and I noticed that the PrepareContainerForItemOverride method is raised earlier in the comboxBox than in the RadComboBox (which is raised only when the user clicks on the combobox).
I'm requesting some help, I would greatly appreciate to benefit from the rich feature set of the radcombobox.
Here's the code for the custom control
public class RadCustomComboBox : RadComboBox |
{ |
public static readonly DependencyProperty NullValueContentProperty = DependencyProperty.Register("NullValueContent", typeof(object), typeof(RadCustomComboBox), new PropertyMetadata(new PropertyChangedCallback(RadCustomComboBox.OnNullValueContentPropertyChanged))); |
public static readonly DependencyProperty NullValueContentTemplateProperty = DependencyProperty.Register("NullValueContentTemplate", typeof(DataTemplate), typeof(RadCustomComboBox), new PropertyMetadata(new PropertyChangedCallback(RadCustomComboBox.OnNullValueContentTemplatePropertyChanged))); |
protected RadComboBoxItem NullValueListBoxItem { get; set; } |
/// <summary> |
/// Gets or sets the NullValueContent value. |
/// </summary> |
public object NullValueContent |
{ |
get { return (object)base.GetValue(RadCustomComboBox.NullValueContentProperty); } |
set { base.SetValue(RadCustomComboBox.NullValueContentProperty, value); } |
} |
/// <summary> |
/// Gets or sets the NullValueContentTemplate value. |
/// </summary> |
public DataTemplate NullValueContentTemplate |
{ |
get { return (DataTemplate)base.GetValue(RadCustomComboBox.NullValueContentTemplateProperty); } |
set { base.SetValue(RadCustomComboBox.NullValueContentTemplateProperty, value); } |
} |
/// <summary> |
/// Initializes a new instance of the <see cref="RadCustomComboBox"/> class. |
/// </summary> |
public RadCustomComboBox() |
: base() |
{ |
base.SelectionChanged += new SelectionChangedEventHandler(RadCustomComboBox_SelectionChanged); |
} |
/// <summary> |
/// Handles the SelectionChanged event of the RadCustomComboBox control. |
/// </summary> |
/// <param name="sender">The source of the event.</param> |
/// <param name="e">The <see cref="Telerik.Windows.Controls.SelectionChangedEventArgs"/> instance containing the event data.</param> |
private void RadCustomComboBox_SelectionChanged(Object sender, SelectionChangedEventArgs e) |
{ |
if (this.SelectedItem == this.NullValueListBoxItem) |
{ |
this.SelectedItem = null; |
this.SelectedValue = null; |
} |
if (!string.IsNullOrEmpty(SelectedValuePath)) |
{ |
object value = null; |
if (SelectedItem != null) |
value = SelectedItem.GetType().GetProperty(SelectedValuePath).GetValue(SelectedItem, null); |
SetValue(RadCustomComboBox.SelectedValueProperty, value); |
} |
} |
/// <summary> |
/// Invoked when the <see cref="P:System.Windows.Controls.ItemsControl.Items"/> property changes. |
/// </summary> |
/// <param name="e">Information about the change.</param> |
protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) |
{ |
switch (e.Action) |
{ |
case NotifyCollectionChangedAction.Reset: |
this.NullValueListBoxItem = null; |
break; |
case NotifyCollectionChangedAction.Remove: |
case NotifyCollectionChangedAction.Replace: |
if (e.OldItems.Contains(null)) this.NullValueListBoxItem = null; |
break; |
} |
object obj = this.SelectedItem; |
base.OnItemsChanged(e); |
this.SelectedItem = obj; |
} |
/// <summary> |
/// Called when [null value content changed]. |
/// </summary> |
/// <param name="oldValue">The old value.</param> |
/// <param name="newValue">The new value.</param> |
private void OnNullValueContentChanged(object oldValue, object newValue) |
{ |
if (this.NullValueListBoxItem != null) |
{ |
this.NullValueListBoxItem.Content = newValue; |
this.OnApplyTemplate(); |
} |
} |
/// <summary> |
/// Called when [null value content template property changed]. |
/// </summary> |
/// <param name="d">The d.</param> |
/// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> |
private static void OnNullValueContentTemplatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
{ |
((RadCustomComboBox)d).OnNullValueContentTemplateChanged((DataTemplate)e.OldValue, (DataTemplate)e.NewValue); |
} |
/// <summary> |
/// Called when [null value content template changed]. |
/// </summary> |
/// <param name="oldValue">The old value.</param> |
/// <param name="newValue">The new value.</param> |
private void OnNullValueContentTemplateChanged(DataTemplate oldValue, DataTemplate newValue) |
{ |
if (this.NullValueListBoxItem != null) |
{ |
this.NullValueListBoxItem.ContentTemplate = newValue; |
this.OnApplyTemplate(); |
} |
} |
protected virtual void OnSelectionChanged(object sender, SelectionChangedEventArgs e) |
{ |
if (this.SelectedItem == this.NullValueListBoxItem) |
{ |
this.SelectedItem = null; |
this.SelectedValue = null; |
} |
} |
/// <summary> |
/// Prepares the specified element to display the specified item. |
/// </summary> |
/// <param name="element">Element used to display the specified item.</param> |
/// <param name="item">Specified item.</param> |
protected override void PrepareContainerForItemOverride(DependencyObject element, object item) |
{ |
base.PrepareContainerForItemOverride(element, item); |
var item2 = element as RadComboBoxItem; |
if (item == null && item2 != null) |
{ |
item2.Content = NullValueContent; |
item2.ContentTemplate = NullValueContentTemplate; |
NullValueListBoxItem = item2; |
} |
} |
/// <summary> |
/// Called when [null value content property changed]. |
/// </summary> |
/// <param name="d">The d.</param> |
/// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> |
private static void OnNullValueContentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
{ |
((RadCustomComboBox)d).OnNullValueContentChanged(e.OldValue, e.NewValue); |
} |
} |
Thanks!