Populate combobox with collection other than the one the Grid it is in is bound to
I have the following code:
<Grid DataContext="{Binding ItemTypes}">
...
<TextBlock Text="Name:" />
<TextBox Grid.Column="2" Text="{Binding Name}" />
<TextBlock Grid.Row="1" Text="Description:" />
<TextBox Grid.Column="1" Grid.Row="1" Text="{Binding Description}" />
<TextBlock Grid.Row="2" Text="Manufacturer:" />
<ComboBox Grid.Column="1" Grid.Row="2" />
<TextBlock Grid.Row="3" Text="Short Name:" />
<TextBox Grid.Column="1" Grid.Row="3" Text="{Binding ShortName}" />
</Grid>
The ItemTypes that the Grid's DataContext is set with, comes from a ViewModel that holds yet another collection. The Manufacturer Combobox that's inside this Grid needs to be filled with the other collection. I tried this:
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType=Window, AncestorLevel=1}, Path=DataContext.companies}"
But it didn't work. How can I get the combobox to fill with the other collection than the one the Grid is bound to?
ViewModel code:
public class ItemTypeViewModel
{
#region private fields
private ICollectionView collectionView;
private IItemTypeService itemTypeService;
#endregion
#region automatic properties
public ObservableCollection<ItemTypeViewModel> ItemTypes { get; private set; }
public IEnumerable<Company> companies { get; private set; }
#endregion properties
#region constructors
public ItemTypeAdminViewModel(IItemTypeService itemTypeService)
{
this.itemTypeService = itemTypeService;
Initialize();
collectionView = CollectionViewSource.GetDefaultView(ItemTypes);
}
#endregion
#region private methods
private void Initialize()
{
//TODO figure out if I should I wrap in Try/Catch here
ItemTypes = new ObservableCollection<ItemTypeViewModel>(itemTypeService.GetItemTypes());
companies = itemTypeService.GetCompanies();
}
#endregion
#region commands
public ICommand GoToFirst
{
get
{
return new RelayCommand(() => collectionView.MoveCurrentToFirst(),
() => collectionView.CurrentPosition >= 1);
}
}
public ICommand GoToLast
{
get
{
return new RelayCommand(() => collectionView.MoveCurrentToLast(),
() => collectionView.CurrentPosition < (ItemTypes.Count - 1));
}
}
public ICommand NextCommand
{
get
{
return new RelayCommand(() => 开发者_JS百科collectionView.MoveCurrentToNext(),
() => collectionView.CurrentPosition < (ItemTypes.Count - 1));
}
}
public ICommand PreviousCommand
{
get
{
return new RelayCommand(() => collectionView.MoveCurrentToPrevious(),
() => collectionView.CurrentPosition >= 1);
}
}
#endregion
}
}
Assuming your view model is set to Window.DataContext
and your other collection MyOtherCollection
is a property in the view model. Change your ComboBox
to the following:
<ComboBox Grid.Column="1" Grid.Row="2"
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}, Path=DataContext.MyOtherCollection}" />
What's assigned to datacontext of the view in its constructor. If you assign view's datacontext to be the viewmodel through constructor injection, you should be able to directly bind as ItemsSource="{Binding companies}"
I would say just don't set the DataContext
on the Grid
. Instead, bind each item individually. It's difficult to give further advice unless you give further information - specifically, your VM.
精彩评论