I can think of two ways to do that, and since you didn't provide your exact case, i will provide a simple scenario and build my answer base on it,
let say you have a DataGrid
with two editable columns (A and B), in the edit mode you can choose the A value from a combobox
list, and then the B combobox
will be filtered to show only the items whom their value starts with the A value for example, if A="aa", B should be {"aaaa","aabb"}, to implement that you need first a Model that represent the DataGrid
Items
public class GridItem
{
public String A { get; set; }
public String B { get; set; }
}
In your codebehind / ViewModel define those properties (the DataGrid
, and the comboboxes
ItemSource Collections) :
private ObservableCollection<GridItem> _gridItemsCollection = new ObservableCollection<GridItem>()
{
new GridItem()
{
A="aa",
B="bbbb"
}
};
public ObservableCollection<GridItem> GridItemsCollection
{
get
{
return _gridItemsCollection;
}
set
{
if (_gridItemsCollection == value)
{
return;
}
_gridItemsCollection = value;
OnPropertyChanged();
}
}
//for the first Combobox
private ObservableCollection<String> _aCollection = new ObservableCollection<String>()
{
"aa",
"bb"
};
public ObservableCollection<String> ACollection
{
get
{
return _aCollection;
}
set
{
if (_aCollection == value)
{
return;
}
_aCollection = value;
OnPropertyChanged();
}
}
//for the second Combobox
private ObservableCollection<String> _bCollection ;
public ObservableCollection<String> BCollection
{
get
{
return _bCollection;
}
set
{
if (_bCollection == value)
{
return;
}
_bCollection = value;
OnPropertyChanged();
}
}
Define a full B collection from which your B
combobox
's itemsource will be populated
ObservableCollection<String> MainBCollection = new ObservableCollection<String>()
{
"aaaa",
"aabb",
"bbaa",
"bbbb"
};
Finally the population of the B combobox
will be based on the selected item in the A
combobox
using this property,
private String _selectedAItem;
public String SelectedAItem
{
get
{
return _selectedAItem;
}
set
{
if (_selectedAItem == value)
{
return;
}
_selectedAItem = value;
OnPropertyChanged();
var returnedCollection = new ObservableCollection<String>();
foreach (var val in MainBCollection)
{
if (val.StartsWith(_selectedAItem))
{
returnedCollection.Add(value);
}
}
BCollection = new ObservableCollection<string>(returnedCollection);
}
}
You need of course to implement the INotifypropertyChanged
Interface, so that the B Combobox
Itemsource will be updated,
Now regarding the Xaml, due to some limitations in Xceed you need to specify the Combobox
's ItemSource
and SelectedItem
using the RelativeSource
and Ancestor
binding,
<Grid >
<xcdg:DataGridControl ItemsSource="{Binding GridItemsCollection}" AutoCreateColumns="False" SelectionMode="Single" >
<xcdg:DataGridControl.Columns>
<xcdg:Column Title="A"
FieldName="A"
>
<xcdg:Column.CellContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</xcdg:Column.CellContentTemplate>
<xcdg:Column.CellEditor>
<xcdg:CellEditor>
<xcdg:CellEditor.EditTemplate>
<DataTemplate>
<ComboBox Name="AComboBox" SelectedItem="{Binding SelectedAItem, RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}}}" SelectedValue="{xcdg:CellEditorBinding}"
ItemsSource="{Binding RelativeSource=
{RelativeSource FindAncestor,
AncestorType={x:Type wpfApplication3:MainWindow}},
Path=ACollection}">
</ComboBox>
</DataTemplate>
</xcdg:CellEditor.EditTemplate>
</xcdg:CellEditor>
</xcdg:Column.CellEditor>
</xcdg:Column>
<xcdg:Column Title="B"
FieldName="B"
>
<xcdg:Column.CellContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</xcdg:Column.CellContentTemplate>
<xcdg:Column.CellEditor>
<xcdg:CellEditor>
<xcdg:CellEditor.EditTemplate>
<DataTemplate>
<ComboBox Name="AComboBox" SelectedValue="{xcdg:CellEditorBinding}" ItemsSource="{Binding RelativeSource=
{RelativeSource FindAncestor,
AncestorType={x:Type Window}},
Path=BCollection}">
</ComboBox>
</DataTemplate>
</xcdg:CellEditor.EditTemplate>
</xcdg:CellEditor>
</xcdg:Column.CellEditor>
</xcdg:Column>
</xcdg:DataGridControl.Columns>
</xcdg:DataGridControl>
</Grid>
and the result is something like that

The Other way to do that is by using a MultivalueConverter
and update the B Collection eachtime the A SelectedValue
is changed,
something like that :
<xcdg:CellEditor.EditTemplate>
<DataTemplate>
<ComboBox Name="AComboBox" SelectedValue="{xcdg:CellEditorBinding}">
<ComboBox.ItemsSource>
<MultiBinding Converter="{StaticResource BCollectionConverter}">
<Binding Path="BCollection" RelativeSource="{RelativeSource AncestorType={x:Type Window}}"/>
<Binding Path="SelectedValue" ElementName="AComboBox" />
</MultiBinding>
</ComboBox.ItemsSource>
</ComboBox>
</DataTemplate>
</xcdg:CellEditor.EditTemplate>
And implement the converter to update the B Combobox
's ItemSource
,
public class BCollectionConverter:IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null)
return null;
var bCollection = (values[0] as ObservableCollection<String>);
var aSelectedItem = (values[1] as String);
if (aSelectedItem == null)
return null;
var returnedCollection = new ObservableCollection<String>();
foreach (var value in bCollection)
{
if (value.StartsWith(aSelectedItem))
{
returnedCollection.Add(value);
}
}
return returnedCollection;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
I didn't try that last one, you might as well give it a try, I hope that did help.