So. I'm having a RadGridView which looks something like this (simplified)
<Grid DataContext="{Binding}" Margin="5,5,5,5" MaxHeight="300" MinHeight="100">
<telerik:RadGridView x:Name="DeliverableTypesGridView" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
ShowGroupPanel="False"
SelectionMode="Single"
AutoGenerateColumns="False"
CanUserReorderColumns="False"
CanUserDeleteRows="False"
CanUserInsertRows="True"
ShowInsertRow="True"
ItemsSource="{Binding DeliverableTypes}">
<telerik:RadGridView.Columns>
<telerik:GridViewSelectColumn />
<telerik:GridViewDataColumn Header="Code" DataMemberBinding="{Binding Code, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />
<telerik:GridViewDataColumn Header="DeliverableType" DataMemberBinding="{Binding Description}" IsReadOnly="True" />
<telerik:GridViewComboBoxColumn Header="Due Date Rule"
DataMemberBinding="{Binding DueDateRule.Description, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding ReferenceData.AllDueDateRules}"
DisplayMemberPath="Description"
/>
<telerik:GridViewCheckBoxColumn Header="Active" DataMemberBinding="{Binding Active}" />
<telerik:GridViewDataColumn Header="Comments" DataMemberBinding="{Binding Comments}"/>
<telerik:GridViewDataColumn Header="Created By" DataMemberBinding="{Binding CreatedBy}" IsReadOnly="True" />
<telerik:GridViewDataColumn Header="Created On" DataFormatString="{}{0:M/d/yyyy}" IsVisible="True" DataMemberBinding="{Binding CreatedOn}" IsReadOnly="True"/>
<telerik:GridViewDataColumn Header="Last Modified By" DataMemberBinding="{Binding LastModifiedBy}" IsReadOnly="True"/>
<telerik:GridViewDataColumn Header="Last Modified On" DataFormatString="{}{0:M/d/yyyy}" IsVisible="True" DataMemberBinding="{Binding LastModifiedOn}" IsReadOnly="True"/>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
</Grid>
Concentrate on the GridViewComboBoxColumn. I'm successfully binding my item source to the combo box on every row has.
But the thing is that when the Grid appears on the screen the GridViewComboBoxColumn column shows no information.
As I'm using WPF MVVM pattern I'm having a public ObservableCollection<DeliverableTypeModel> DeliverableTypes property on a ManageDeliverableViewModel.cs whcih I use as DataConext. My DeliverableTypeModel.cs has a DeliverableDueDateRule Property as well.
My intention is to show the value that the DeliverableDueDateRule Property has under this field in the grid ,
but I get a blank column instead.
The thing that is working is that when I click on a cell of the blank column I get a comboBox whith the items on the items source
Thanks!
13 Answers, 1 is accepted
In order to provide you with an appropriate solution, I would need a bit more information about your project and more specifically about the ItemsSource of the GridViewComboBoxColumn. Basically, the Property set for the DataMemberBinding needs to correspond to a property in the ItemsSource of the grid. This is the way the two elements - the column and the grid - communicate and know which item should appear in the ComboBoxColumn.
I am sending you a sample project illustrating the implementation of the GridViewComboBoxColumn.
Maya
the Telerik team
You can define the Source property of the Binding explicitly pointing to your ViewModel. For example:
<
telerik:GridViewComboBoxColumn
Header
=
"Category"
DataMemberBinding
=
"{Binding CategoryID}"
ItemsSource
=
"{Binding Path=Categories, Source={StaticResource mainPageViewModel}}"
DisplayMemberPath
=
"CategoryName"
SelectedValueMemberPath
=
"CategoryID"
/>
In the project above you can follow the same idea (however, you will need to define Countries property in your ViewModel).
You can take a look at this article for a reference as well.
Maya
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
public
class
Campaign
{
public
Employee Employee {
get
;
set
:}
}
public
class
Employee
{
public
string
Id {
get
;
set
:}
public
string
Name {
get
;
set
:}
public
string
Rank {
get
;
set
:}
}
ViewModel has:
ObservableColelction<Employee> Employees;
ObservableColelction<Campaigns> Campaigns;
XAML:
<UserControl.Resources>
<CollectionViewSource x:Key=
"EmployeeViewSource"
Source=
"{Binding Employees}"
/>
</UserControl.Resources>
<Controls:RadGridView x:Name=
"CampignGridView"
ItemsSource=
"{Binding Path=Campaigns}"
>
<Controls:RadGridView.Columns>
<telerik:GridViewComboBoxColumn Header=
"Employee"
DataMemberBinding=
"{Binding Employee.Id, Mode=TwoWay}"
ItemsSource=
"{Binding Source={StaticResource EmployeeViewSource}}"
SelectedValueMemberPath=
"Id"
DisplayMemberPath=
"Name"
/>
<telerik:GridViewDataColumn Header=
"Rank"
?????? " />
</Controls:RadGridView.Columns>
</Controls:RadGridView
There are a couple of possible approaches here. For example:
1. You can define RadComboBox in a CellEditTemplate for the combo box column and work with its SelectedValue, SelectedItem, etc. properties.
2. You can add handler for SelectionChanged event of RadComboBox (just as illustrated in this forum thread) and update the value of the 'Rank' property, once you make any selection.
3. You can perform all that logic inside the implementation of your business object - once Id property is updated (when a new value is selected from the combo box column), you can update the value of the 'Rank' property as well.
Let me know if you have any difficulties implementing the one that is most appropriate for you.
Maya
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
How can i add event handler for selection changed through MVVM way???
Could you give me some sample or snippet how to do this?
Thanks in Advance!
You cannot add handler in the ViewModel as it is in the second suggested approach. If you follow the first approach and work directly with RadComboBox, you can create an attached behavior for it and keep your code behind clean.
Maya
Telerik
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
GridViewComboBoxColumn is read only property is not disabling the combo box
I have tested the scenario, but I was not able to reproduce it. I am attaching the sample I used for the test. Will it be possible to take a look at it and let me know if I am missing anything ?
Regards,
Maya
Telerik
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
Hi,
my scenario is nearly the same. The problem is that the ComboBox column shows the same text (of the first row) in every Row and when I select another dye the ComboBoxColumn doesn't actualize the text.
My Datamodel consists of three tables. The Recipe table, Dye table and the RecipeDye table which describes which Dyes belong to a Recipe.
I have a GridView which lists the Dyes that belong to the selected Recipe. The user can edit the rows of the GridView to edit the dyes of the recipe. For that I want a ComboBoxCell which lists the available dyes and displays the name of the selected dye.
I hope my description was understandable, here is the XAML Code and the code of the three ViewModels:
<
telerik:RadGridView
x:Name
=
"gvRecipeDye"
Grid.Row
=
"1"
Grid.RowSpan
=
"4"
Grid.Column
=
"6"
ShowGroupPanel
=
"False"
CanUserFreezeColumns
=
"False"
IsFilteringAllowed
=
"False"
SelectionMode
=
"Single"
RowIndicatorVisibility
=
"Collapsed"
CanUserInsertRows
=
"True"
DataContext
=
"{StaticResource RecipeDyeViewModel}"
ItemsSource
=
"{Binding RecipeDye}"
Width
=
"300"
AutoGenerateColumns
=
"False"
NewRowPosition
=
"Bottom"
GroupRenderMode
=
"Flat"
>
<
telerik:RadGridView.Columns
>
<
telerik:GridViewDataColumn
Name
=
"cColor"
Header
=
"Farbe"
IsReadOnly
=
"True"
CellStyle
=
"{StaticResource GridViewCellStyleColor}"
/>
<
telerik:GridViewComboBoxColumn
Width
=
"2*"
Name
=
"cDyeDescription"
Header
=
"Bezeichnung"
DataContext
=
"{StaticResource DyeViewModel}"
ItemsSource
=
"{Binding Dye}"
DataMemberBinding
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type telerik:RadGridView}},Path=DataContext.Id_Dye}"
DisplayMemberPath
=
"Name"
SelectedValueMemberPath
=
"Id_Dye"
/>
<
telerik:GridViewMaskedInputColumn
MaskType
=
"Numeric"
Width
=
"1*"
Name
=
"cDyeQuantity"
Header
=
"Menge (g)"
DataMemberBinding
=
"{Binding DyeQuantity}"
/>
</
telerik:RadGridView.Columns
>
</
telerik:RadGridView
>
using
System;
using
System.Collections.Generic;
using
System.Collections.ObjectModel;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Linq;
using
System.Runtime.CompilerServices;
using
System.Windows;
using
System.Windows.Media;
using
Telerik.Windows.Controls;
using
WpfCodebase;
namespace
DyeingControl
{
public
class
Recipe : INotifyPropertyChanged
{
public
int
Id
{
get
{
return
GetPropertyValue<
int
>(); }
set
{ SetPropertyValue(value); }
}
public
Visibility NewRecipe
{
get
{
return
GetPropertyValue<Visibility>(); }
set
{ SetPropertyValue(value); }
}
public
bool
Saved
{
get
{
return
GetPropertyValue<
bool
>(); }
set
{ SetPropertyValue(value); }
}
public
int
Id_MachineType
{
get
{
return
GetPropertyValue<
int
>(); }
set
{
SetPropertyValue(value);
}
}
public
int
Id_RecipeStatus
{
get
{
return
GetPropertyValue<
int
>(); }
set
{ SetPropertyValue(value); }
}
public
int
Id_DyeType
{
get
{
return
GetPropertyValue<
int
>(); }
set
{ SetPropertyValue(value); }
}
public
SolidColorBrush Color
{
get
{
return
GetPropertyValue<SolidColorBrush>(); }
set
{
SetPropertyValue(value);
}
}
public
string
Name
{
get
{
return
GetPropertyValue<
string
>(); }
set
{ SetPropertyValue(value); }
}
public
string
Fleet
{
get
{
return
GetPropertyValue<
string
>(); }
set
{ SetPropertyValue(value); }
}
public
MachineType SelectedMachineType
{
get
{
return
GetPropertyValue<MachineType>(); }
set
{
SetPropertyValue(value);
}
}
public
string
RecipeStatus
{
get
{
return
GetPropertyValue<
string
>(); }
set
{ SetPropertyValue(value); }
}
public
RecipeStatus SelectedRecipeStatus
{
get
{
return
GetPropertyValue<RecipeStatus>(); }
set
{
SetPropertyValue(value);
}
}
public
string
DyeTypeTitle
{
get
{
return
GetPropertyValue<
string
>(); }
set
{
SetPropertyValue(value);
}
}
public
DyeType SelectedDyeType
{
get
{
return
GetPropertyValue<DyeType>(); }
set
{
SetPropertyValue(value);
}
}
public
string
Creator
{
get
{
return
GetPropertyValue<
string
>(); }
set
{ SetPropertyValue(value); }
}
public
string
Created
{
get
{
return
GetPropertyValue<
string
>(); }
set
{ SetPropertyValue(value); }
}
public
string
LastEditedBy
{
get
{
return
GetPropertyValue<
string
>(); }
set
{ SetPropertyValue(value); }
}
public
string
LastEdited
{
get
{
return
GetPropertyValue<
string
>(); }
set
{ SetPropertyValue(value); }
}
#region Constructors
public
Recipe()
{
this
.Name =
string
.Empty;
this
.Creator =
string
.Empty;
this
.Created =
null
;
this
.LastEditedBy =
string
.Empty;
this
.LastEdited =
null
;
this
.Fleet =
string
.Empty;
this
.RecipeStatus =
string
.Empty;
this
.DyeTypeTitle =
string
.Empty;
this
.NewRecipe = Visibility.Visible;
this
.Saved =
false
;
}
public
Recipe(
int
id,
string
color,
string
name,
int
id_MachineType,
string
fleet,
int
id_RecipeStatus,
string
status,
int
id_DyeType,
string
dyeTypeTitle,
string
creator,
string
created,
string
lastEditedBy,
string
lastEdited)
{
this
.Id = id;
this
.Name = name;
this
.Creator = creator;
this
.Created = created;
this
.LastEditedBy = lastEditedBy;
this
.LastEdited = lastEdited;
this
.Fleet = fleet;
this
.RecipeStatus = status;
this
.DyeTypeTitle = dyeTypeTitle;
this
.SelectedMachineType = MachineTypeViewModel.MachineTypes.Where(x => x.Id == id_MachineType).First();
this
.SelectedRecipeStatus = RecipeStatusViewModel.RecipeStatuses.Where(x => x.Id == id_RecipeStatus).First();
this
.SelectedDyeType = DyeTypeViewModel.DyeTypes.Where(x => x.Id == id_DyeType).First();
System.Drawing.Color clrTemp = ColorTranslator.FromHtml(color);
this
.Color =
new
SolidColorBrush(System.Windows.Media.Color.FromArgb(clrTemp.A, clrTemp.R, clrTemp.G, clrTemp.B));
this
.NewRecipe = Visibility.Collapsed;
this
.Saved =
true
;
}
#endregion
#region DO NOT CHANGE!
private
ILookup<
string
,
string
> _dependentLookup;
private
ILookup<
string
,
string
> DependentLookup
{
get
{
return
_dependentLookup ?? (_dependentLookup = (from p
in
GetType().GetProperties()
let attrs = p.GetCustomAttributes(
typeof
(NotifiesOnAttribute),
false
)
from NotifiesOnAttribute a
in
attrs
select
new
{ Independent = a.Name, Dependent = p.Name }).ToLookup(i => i.Independent, d => d.Dependent));
}
}
protected
void
RaisePropertyChanged([CallerMemberName]
string
propertyName =
null
)
{
if
(propertyName ==
null
)
throw
new
ArgumentNullException(
"propertyName"
);
var propertyChanged = PropertyChanged;
if
(propertyChanged !=
null
)
{
propertyChanged(
this
,
new
PropertyChangedEventArgs(propertyName));
foreach
(var dependentPropertyName
in
DependentLookup[propertyName])
{
RaisePropertyChanged(dependentPropertyName);
}
}
}
public
event
PropertyChangedEventHandler PropertyChanged;
private
readonly
Dictionary<
string
,
object
> _propertyBackingDictionary =
new
Dictionary<
string
,
object
>();
protected
virtual
void
OnPropertyChanged(PropertyChangedEventArgs args)
{
PropertyChangedEventHandler handler =
this
.PropertyChanged;
if
(handler !=
null
)
{
handler(
this
, args);
}
}
private
void
OnPropertyChanged([CallerMemberName]
string
propertyName =
null
)
{
this
.OnPropertyChanged(
new
PropertyChangedEventArgs(propertyName));
}
protected
T GetPropertyValue<T>([CallerMemberName]
string
propertyName =
null
)
{
if
(propertyName ==
null
)
throw
new
ArgumentNullException(
"propertyName"
);
object
value;
if
(_propertyBackingDictionary.TryGetValue(propertyName,
out
value))
{
return
(T)value;
}
return
default
(T);
}
protected
bool
SetPropertyValue<T>(T newValue, [CallerMemberName]
string
propertyName =
null
)
{
if
(propertyName ==
null
)
throw
new
ArgumentNullException(
"propertyName"
);
if
(EqualityComparer<T>.Default.Equals(newValue, GetPropertyValue<T>(propertyName)))
return
false
;
_propertyBackingDictionary[propertyName] = newValue;
OnPropertyChanged(propertyName);
return
true
;
}
#endregion
}
public
class
RecipeViewModel : ViewModelBase
{
private
ObservableCollection<Recipe> recipe;
public
ObservableCollection<Recipe> Recipe
{
get
{
if
(
this
.recipe ==
null
)
{
this
.recipe =
this
.CreateRecipes();
}
return
this
.recipe;
}
}
private
ObservableCollection<Recipe> CreateRecipes()
{
ObservableCollection<Recipe> recipes =
new
ObservableCollection<Recipe>();
Recipe recipe;
foreach
(DataRow recipeRow
in
RecipeManagement.dtRecipes.Rows)
{
recipe =
new
Recipe(Convert.ToInt32(recipeRow[
"Id"
]), recipeRow[
"Color"
].ToString(), recipeRow[
"Name"
].ToString(),
Convert.ToInt32(recipeRow[
"Id_MachineType"
]), recipeRow[
"Fleet"
].ToString(),
Convert.ToInt32(recipeRow[
"Id_RecipeStatus"
]), recipeRow[
"Status"
].ToString(),
Convert.ToInt32(recipeRow[
"Id_DyeType"
]), recipeRow[
"DyeTypeTitle"
].ToString(),
recipeRow[
"Creator"
].ToString(), recipeRow[
"Created"
].ToString(), recipeRow[
"LastEditedBy"
] != DBNull.Value ? recipeRow[
"LastEditedBy"
].ToString() :
string
.Empty,
recipeRow[
"LastEdited"
] != DBNull.Value ? recipeRow[
"LastEdited"
].ToString() :
string
.Empty);
recipes.Add(recipe);
}
return
recipes;
}
}
}
using
System;
using
System.Collections.Generic;
using
System.Collections.ObjectModel;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Linq;
using
System.Runtime.CompilerServices;
using
System.Windows;
using
System.Windows.Media;
using
Telerik.Windows.Controls;
using
WpfCodebase;
namespace
DyeingControl
{
public
class
Dye : INotifyPropertyChanged
{
public
int
Id
{
get
{
return
GetPropertyValue<
int
>(); }
set
{ SetPropertyValue(value); }
}
public
Visibility NewDye
{
get
{
return
GetPropertyValue<Visibility>(); }
set
{ SetPropertyValue(value); }
}
public
bool
Saved
{
get
{
return
GetPropertyValue<
bool
>(); }
set
{ SetPropertyValue(value); }
}
public
SolidColorBrush DyeColor
{
get
{
return
GetPropertyValue<SolidColorBrush>(); }
set
{
SetPropertyValue(value);
}
}
public
string
Name
{
get
{
return
GetPropertyValue<
string
>(); }
set
{
SetPropertyValue(value);
}
}
public
string
Manufacturer
{
get
{
return
GetPropertyValue<
string
>(); }
set
{
SetPropertyValue(value);
}
}
public
string
Description
{
get
{
return
GetPropertyValue<
string
>(); }
set
{
SetPropertyValue(value);
}
}
public
DyeType SelectedDyeType
{
get
{
return
GetPropertyValue<DyeType>(); }
set
{
SetPropertyValue(value);
}
}
public
int
Id_Type
{
get
{
return
GetPropertyValue<
int
>(); }
set
{ SetPropertyValue(value); }
}
public
string
TypeTitle
{
get
{
return
GetPropertyValue<
string
>(); }
set
{
SetPropertyValue(value);
}
}
#region Constructors
public
Dye()
{
this
.Name =
string
.Empty;
this
.Manufacturer =
string
.Empty;
this
.Description =
string
.Empty;
this
.TypeTitle =
string
.Empty;
this
.NewDye = Visibility.Visible;
this
.Saved =
false
;
}
public
Dye(
int
id,
string
color,
string
name,
string
description,
string
manufacturer,
string
descriptionType,
int
id_DyeType)
{
this
.Id = id;
this
.Id_Type = id_DyeType;
this
.Name = name;
this
.Manufacturer = manufacturer;
this
.Description = description;
this
.TypeTitle = descriptionType;
System.Drawing.Color clrTemp = ColorTranslator.FromHtml(color);
this
.DyeColor =
new
SolidColorBrush(System.Windows.Media.Color.FromArgb(clrTemp.A, clrTemp.R, clrTemp.G, clrTemp.B));
this
.SelectedDyeType = DyeTypeViewModel.DyeTypes.Where(x => x.Id == id_DyeType).First();
this
.NewDye = Visibility.Collapsed;
this
.Saved =
true
;
}
#endregion
#region DO NOT CHANGE!
private
ILookup<
string
,
string
> _dependentLookup;
private
ILookup<
string
,
string
> DependentLookup
{
get
{
return
_dependentLookup ?? (_dependentLookup = (from p
in
GetType().GetProperties()
let attrs = p.GetCustomAttributes(
typeof
(NotifiesOnAttribute),
false
)
from NotifiesOnAttribute a
in
attrs
select
new
{ Independent = a.Name, Dependent = p.Name }).ToLookup(i => i.Independent, d => d.Dependent));
}
}
protected
void
RaisePropertyChanged([CallerMemberName]
string
propertyName =
null
)
{
if
(propertyName ==
null
)
throw
new
ArgumentNullException(
"propertyName"
);
var propertyChanged = PropertyChanged;
if
(propertyChanged !=
null
)
{
propertyChanged(
this
,
new
PropertyChangedEventArgs(propertyName));
foreach
(var dependentPropertyName
in
DependentLookup[propertyName])
{
RaisePropertyChanged(dependentPropertyName);
}
}
}
public
event
PropertyChangedEventHandler PropertyChanged;
private
readonly
Dictionary<
string
,
object
> _propertyBackingDictionary =
new
Dictionary<
string
,
object
>();
protected
virtual
void
OnPropertyChanged(PropertyChangedEventArgs args)
{
PropertyChangedEventHandler handler =
this
.PropertyChanged;
if
(handler !=
null
)
{
handler(
this
, args);
}
}
private
void
OnPropertyChanged([CallerMemberName]
string
propertyName =
null
)
{
this
.OnPropertyChanged(
new
PropertyChangedEventArgs(propertyName));
}
protected
T GetPropertyValue<T>([CallerMemberName]
string
propertyName =
null
)
{
if
(propertyName ==
null
)
throw
new
ArgumentNullException(
"propertyName"
);
object
value;
if
(_propertyBackingDictionary.TryGetValue(propertyName,
out
value))
{
return
(T)value;
}
return
default
(T);
}
protected
bool
SetPropertyValue<T>(T newValue, [CallerMemberName]
string
propertyName =
null
)
{
if
(propertyName ==
null
)
throw
new
ArgumentNullException(
"propertyName"
);
if
(EqualityComparer<T>.Default.Equals(newValue, GetPropertyValue<T>(propertyName)))
return
false
;
_propertyBackingDictionary[propertyName] = newValue;
OnPropertyChanged(propertyName);
return
true
;
}
#endregion
}
public
class
DyeViewModel : ViewModelBase
{
private
static
ObservableCollection<Dye> dye;
public
static
ObservableCollection<Dye> Dye
{
get
{
if
(DyeViewModel.dye ==
null
)
{
DyeViewModel.dye = DyeViewModel.CreateDyes();
}
return
DyeViewModel.dye;
}
}
private
static
ObservableCollection<Dye> CreateDyes()
{
ObservableCollection<Dye> dyes =
new
ObservableCollection<Dye>();
Dye dye;
foreach
(DataRow dyeRow
in
RecipeManagement.dtDye.Rows)
{
dye =
new
Dye(Convert.ToInt32(dyeRow[
"Id"
]), dyeRow[
"color"
].ToString(), dyeRow[
"Name"
].ToString(), dyeRow[
"Description"
].ToString(), dyeRow[
"Manufacturer"
].ToString(),
dyeRow[
"Type"
].ToString(), Convert.ToInt32(dyeRow[
"Id_DyeType"
]));
dyes.Add(dye);
}
return
dyes;
}
}
}
using
System;
using
System.Collections.Generic;
using
System.Collections.ObjectModel;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Linq;
using
System.Runtime.CompilerServices;
using
System.Windows.Media;
using
Telerik.Windows.Controls;
using
WpfCodebase;
namespace
DyeingControl
{
public
class
RecipeDye : INotifyPropertyChanged
{
public
int
Id
{
get
{
return
GetPropertyValue<
int
>(); }
set
{ SetPropertyValue(value); }
}
public
int
Id_Recipe
{
get
{
return
GetPropertyValue<
int
>(); }
set
{ SetPropertyValue(value); }
}
public
int
Id_Dye
{
get
{
return
GetPropertyValue<
int
>(); }
set
{ SetPropertyValue(value); }
}
public
string
DyeName
{
get
{
return
GetPropertyValue<
string
>(); }
set
{ SetPropertyValue(value); }
}
public
decimal
DyeQuantity
{
get
{
return
GetPropertyValue<
decimal
>(); }
set
{ SetPropertyValue(value); }
}
public
SolidColorBrush Color
{
get
{
return
GetPropertyValue<SolidColorBrush>(); }
set
{ SetPropertyValue(value); }
}
public
RecipeDye(
int
id,
int
id_recipe,
int
id_dye,
decimal
dyequantity)
{
this
.Id = id;
this
.Id_Recipe = id_recipe;
this
.Id_Dye = id_dye;
this
.DyeName = (DyeViewModel.Dye.Where(x => x.Id == id_dye).First()).Name;
this
.DyeQuantity = dyequantity;
this
.Color = (DyeViewModel.Dye.Where(x => x.Id == id_dye).First()).DyeColor;
}
public
RecipeDye(
int
id,
int
id_recipe,
int
id_dye,
string
dyename,
decimal
dyequantity,
string
color)
{
this
.Id = id;
this
.Id_Recipe = id_recipe;
this
.Id_Dye = id_dye;
this
.DyeName = dyename;
this
.DyeQuantity = dyequantity;
System.Drawing.Color clrTemp = ColorTranslator.FromHtml(color);
this
.Color =
new
SolidColorBrush(System.Windows.Media.Color.FromArgb(clrTemp.A, clrTemp.R, clrTemp.G, clrTemp.B));
}
#region Fixed Methods
private
ILookup<
string
,
string
> _dependentLookup;
private
ILookup<
string
,
string
> DependentLookup
{
get
{
return
_dependentLookup ?? (_dependentLookup = (from p
in
GetType().GetProperties()
let attrs = p.GetCustomAttributes(
typeof
(NotifiesOnAttribute),
false
)
from NotifiesOnAttribute a
in
attrs
select
new
{ Independent = a.Name, Dependent = p.Name }).ToLookup(i => i.Independent, d => d.Dependent));
}
}
protected
void
RaisePropertyChanged([CallerMemberName]
string
propertyName =
null
)
{
if
(propertyName ==
null
)
throw
new
ArgumentNullException(
"propertyName"
);
var propertyChanged = PropertyChanged;
if
(propertyChanged !=
null
)
{
propertyChanged(
this
,
new
PropertyChangedEventArgs(propertyName));
foreach
(var dependentPropertyName
in
DependentLookup[propertyName])
{
RaisePropertyChanged(dependentPropertyName);
}
}
}
public
event
PropertyChangedEventHandler PropertyChanged;
private
readonly
Dictionary<
string
,
object
> _propertyBackingDictionary =
new
Dictionary<
string
,
object
>();
protected
virtual
void
OnPropertyChanged(PropertyChangedEventArgs args)
{
PropertyChangedEventHandler handler =
this
.PropertyChanged;
if
(handler !=
null
)
{
handler(
this
, args);
}
}
private
void
OnPropertyChanged([CallerMemberName]
string
propertyName =
null
)
{
this
.OnPropertyChanged(
new
PropertyChangedEventArgs(propertyName));
}
protected
T GetPropertyValue<T>([CallerMemberName]
string
propertyName =
null
)
{
if
(propertyName ==
null
)
throw
new
ArgumentNullException(
"propertyName"
);
object
value;
if
(_propertyBackingDictionary.TryGetValue(propertyName,
out
value))
{
return
(T)value;
}
return
default
(T);
}
protected
bool
SetPropertyValue<T>(T newValue, [CallerMemberName]
string
propertyName =
null
)
{
if
(propertyName ==
null
)
throw
new
ArgumentNullException(
"propertyName"
);
if
(EqualityComparer<T>.Default.Equals(newValue, GetPropertyValue<T>(propertyName)))
return
false
;
_propertyBackingDictionary[propertyName] = newValue;
OnPropertyChanged(propertyName);
return
true
;
}
#endregion
}
public
class
RecipeDyeViewModel : ViewModelBase
{
private
static
ObservableCollection<RecipeDye> recipedye;
public
static
ObservableCollection<RecipeDye> RecipeDye
{
get
{
if
(RecipeDyeViewModel.recipedye ==
null
)
{
RecipeDyeViewModel.recipedye = RecipeDyeViewModel.CreateRecipeDye();
}
return
RecipeDyeViewModel.recipedye;
}
}
private
static
ObservableCollection<RecipeDye> CreateRecipeDye()
{
ObservableCollection<RecipeDye> recipedyes =
new
ObservableCollection<RecipeDye>();
RecipeDye recipedye;
foreach
(DataRow recipeDyeRow
in
RecipeManagement.dtRecipeDye.Rows)
{
recipedye =
new
RecipeDye(Convert.ToInt32(recipeDyeRow[
"Id"
]), Convert.ToInt32(recipeDyeRow[
"Id_Recipe"
]), Convert.ToInt32(recipeDyeRow[
"Id_Dye"
]),
recipeDyeRow[
"Name"
].ToString(), Convert.ToDecimal(recipeDyeRow[
"DyeQuantity"
]), recipeDyeRow[
"Color"
].ToString());
recipedyes.Add(recipedye);
}
return
recipedyes;
}
}
}
Would it be possible to raise a ticket and provide us with a sample project that shows the setup at your end as it would be much easier for us to investigate the issue and advise you accordingly? Apart from that, my advice is to check the demos regarding the GridViewComboBoxColumn in our SDK Samples Browser and the article in our online documentation and make sure that you are following the instructions.
Regards,
Stefan Nenchev
Telerik by Progress
I am experiencing an issue similar to the original post. My question is as follows...
Why does the binding of the gridview itemsource stop working for a column when I specify a binding source on a column?
Given:
Data is a property on the ViewModel of type observablecollection that is the source of the data in the grid.
Machines is a property on the ViewModel of type observablecollection that is the source of the data for the allowable values of the cells in the column.
I am seeing binding errors in the output for the DataMemberBinding assignment indicating that the grid thinks the binding is to Machines and not to Data
<telerik:RadGridView
AutoGenerateColumns="False"
ItemsSource="{Binding Data}"
Margin="5"
CellValidating="CellValidating"
RowValidating="RowValidating">
<telerik:RadGridView.Resources>
</telerik:RadGridView.Resources>
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding DatePartsProduced}"
EditTriggers="Default"
Header="Prod Date"/>
<telerik:GridViewComboBoxColumn
DataMemberBinding="{Binding Path=MachNum}"
ItemsSource="{Binding Machines}"
DisplayMemberPath="MachineNum"
SelectedValueMemberPath="MachineNum"
EditTriggers="Default"
Header="Machine#">
</telerik:GridViewComboBoxColumn>
I think I am missing something basic here,and need some help to see it :-)
Thanks
-Sean
Thank you for the provided xaml.
The reason for the described behavior is that the binding is expecting the Machines collection to be a property of the objects that are in the Data collection. That is because the DataContext of each row is an object from the ItemsSource collection of the RadGridView.
In order to bind the column when the Machines collection is in the view model, you can give the RadGridView an "x:Name" and use an ElementName binding. Here is how that would look provided that the RadGridView has an x:Name="radGridView":
<
telerik:GridViewComboBoxColumn
ItemsSource
=
"{Binding DataContext.Machines, ElementName=radGridView}"
/>
On a side note, you can check out the ComboBoxColumn article in our documentation and also the ComboBoxColumn SDK example.
Please give this a try and let me know how it goes.
Regards,
Vladimir Stoyanov
Progress Telerik