Hi there,
First of all, I would like to thank you to Telerik to create a wonderful ComboBox, it helps me much on my application development career.
Anyway, I have a question regards on using RadComboBox within DataForm.
Here is my case.
- I have a Product Details form created using DataForm of Silverlight Toolkit.
- I have a field ProductCategoryId which is a foreign key linking to ProductCategories table which I would like to let use pick it up from ComboBox, I want to reuse it so I build a Custom Control named "ProductCategoryLookup" and put RadComboBox within it. Here is the XAML for the Custom Control.
- Here is the code behind after the Custom Control. I just added a Dependency Property to be able to do data binding.
- In the DataForm, I put my Custom Control into the data field like this.
- When I run the application, it displays a correct value.
However, I got 2 problems...
So, I think there 2 problems are caused by the same reason that custom control did not notify changes to the DomainDataSource.
I also found some thread that got the same problem with me even he place a RadComboBox directly into the DataForm but I cannot find out a solution within the thread.
From my further research, I found someone talking about Behavior, I also found an example from some thread here about DataSourceBehavior but I cannot figure out how can I apply it in my case. Here is the code I found.
So I would like to ask here for some hints or suggestion.
Keep up the great works!
Thank you and best regards,
Seree Woradechjamroen
First of all, I would like to thank you to Telerik to create a wonderful ComboBox, it helps me much on my application development career.
Anyway, I have a question regards on using RadComboBox within DataForm.
Here is my case.
- I have a Product Details form created using DataForm of Silverlight Toolkit.
- I have a field ProductCategoryId which is a foreign key linking to ProductCategories table which I would like to let use pick it up from ComboBox, I want to reuse it so I build a Custom Control named "ProductCategoryLookup" and put RadComboBox within it. Here is the XAML for the Custom Control.
<Grid x:Name="LayoutRoot" Background="White" HorizontalAlignment="Stretch" Width="Auto"> |
<riaControls:DomainDataSource AutoLoad="True" Height="0" LoadedData="ddsLookup_LoadedData" Name="ddsLookup" QueryName="GetInventoryItemCategoriesByCompanyIdQuery" Width="0"> |
<riaControls:DomainDataSource.DomainContext> |
<my1:MasterContext /> |
</riaControls:DomainDataSource.DomainContext> |
</riaControls:DomainDataSource> |
<Controls1:RadComboBox Name="ComboLookup" IsEditable="True" IsTextSearchEnabled="True" TextSearchMode="StartsWith" ItemsSource="{Binding ElementName=ddsLookup, Path=Data}" DisplayMemberPath="Title" SelectedValuePath="InventoryItemCategoryId" HorizontalContentAlignment="Stretch" UseLayoutRounding="True"> |
</Controls1:RadComboBox> |
</Grid> |
- Here is the code behind after the Custom Control. I just added a Dependency Property to be able to do data binding.
public static readonly DependencyProperty SelectedIdProperty = DependencyProperty.Register( |
"SelectedId", |
typeof(int), |
typeof(InventoryItemCategoryLookup), |
new PropertyMetadata(SelectedIdChanged)); |
public int SelectedId |
{ |
get |
{ |
return (int)this.GetValue(SelectedIdProperty); |
} |
set |
{ |
this.SetValue(SelectedIdProperty, value); |
} |
} |
private static void SelectedIdChanged(object sender, DependencyPropertyChangedEventArgs args) |
{ |
var me = sender as InventoryItemCategoryLookup; |
me.ComboLookup.SelectedValue = args.NewValue; |
if (me.SelectedValueChanged != null) |
me.SelectedValueChanged(); |
} |
- In the DataForm, I put my Custom Control into the data field like this.
<dataFormToolkit:DataField Grid.Row="3" Grid.Column="0" Label="Category" LabelPosition="Auto"> |
<my:InventoryItemCategoryLookup SelectedId="{Binding Path=CategoryId, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnExceptions=True}" Behaviors:DataSourceBehavior.Enable="True"> |
</my:InventoryItemCategoryLookup> |
</dataFormToolkit:DataField> |
- When I run the application, it displays a correct value.
However, I got 2 problems...
- When I change the value by selecting another option from the RadComboBox, the DataForm didn't notified that the data was changed. The Commit button will never appear until I changed another data fields.
- When I click on the Commit button, all changes were saved except the value of my Custom Control which is RadComboBox.
So, I think there 2 problems are caused by the same reason that custom control did not notify changes to the DomainDataSource.
I also found some thread that got the same problem with me even he place a RadComboBox directly into the DataForm but I cannot find out a solution within the thread.
From my further research, I found someone talking about Behavior, I also found an example from some thread here about DataSourceBehavior but I cannot figure out how can I apply it in my case. Here is the code I found.
using System.Windows; |
using System.Windows.Controls; |
using System.Threading; |
using System.Windows.Threading; |
using System.Collections.ObjectModel; |
namespace ComboDataForm |
{ |
public class DataSourceBehavior |
{ |
public static bool GetEnable(DependencyObject obj) |
{ |
return (bool)obj.GetValue(EnableProperty); |
} |
public static void SetEnable(DependencyObject obj, bool value) |
{ |
obj.SetValue(EnableProperty, value); |
} |
public static readonly DependencyProperty EnableProperty = |
DependencyProperty.RegisterAttached("Enable", typeof(bool), typeof(DataSourceBehavior), new PropertyMetadata(OnEnabledPropertyChanged)); |
private static void OnEnabledPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs args) |
{ |
// This will simulate the delay in the getting of the data source from a service |
DispatcherTimer timer = new DispatcherTimer(); |
timer.Tick += (a, b) => |
{ |
// Case #1 |
//var values = new IntVal[] |
//{ |
// new IntVal() { ID = 1, Text = "one" }, |
// new IntVal() { ID = 2, Text = "two" }, |
// new IntVal() { ID = 5, Text = "five" }, |
// new IntVal() { ID = 10, Text = "ten" } |
//}; |
//(d as ItemsControl).ItemsSource = values; |
// Case #2 |
var values = new IntVal[] |
{ |
new IntVal() { ID = 5, Text = "five" }, |
new IntVal() { ID = 1, Text = "one" }, |
new IntVal() { ID = 2, Text = "two" }, |
new IntVal() { ID = 10, Text = "ten" } |
}; |
var source = new ObservableCollection<IntVal>(); |
(d as ItemsControl).ItemsSource = source; |
foreach (var v in values) |
{ |
source.Add(v); |
} |
timer.Stop(); |
}; |
timer.Interval = new System.TimeSpan(0, 0, 0, 0, 500); |
timer.Start(); |
} |
} |
} |
So I would like to ask here for some hints or suggestion.
Keep up the great works!
Thank you and best regards,
Seree Woradechjamroen