#wpf #binding
#wpf #привязка
Вопрос:
У меня есть следующий код:
<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>
Типы элементов, с помощью которых задается DataContext сетки, поступают из ViewModel, которая содержит еще одну коллекцию. Поле со списком производителя, которое находится внутри этой сетки, должно быть заполнено другой коллекцией. Я пробовал это:
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType=Window, AncestorLevel=1}, Path=DataContext.companies}"
Но это не сработало. Как я могу заставить поле со списком заполнить другую коллекцию, отличную от той, к которой привязана сетка?
Код ViewModel:
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(() => collectionView.MoveCurrentToNext(),
() => collectionView.CurrentPosition < (ItemTypes.Count - 1));
}
}
public ICommand PreviousCommand
{
get
{
return new RelayCommand(() => collectionView.MoveCurrentToPrevious(),
() => collectionView.CurrentPosition >= 1);
}
}
#endregion
}
}
Ответ №1:
Предположим, что для вашей модели представления установлено значение Window.DataContext
, а другая ваша коллекция MyOtherCollection
является свойством в модели представления. Измените свой ComboBox
на следующий:
<ComboBox Grid.Column="1" Grid.Row="2"
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}, Path=DataContext.MyOtherCollection}" />
Комментарии:
1. Спасибо за ваш ответ, хотя я пробовал, и у меня это не работает. По-прежнему ничего не отображается.
Ответ №2:
Что назначено datacontext представления в его конструкторе. Если вы назначаете datacontext view для viewmodel посредством внедрения конструктора, вы должны иметь возможность напрямую привязывать как ItemsSource="{Binding companies}"
Комментарии:
1. XAML-код формы на самом деле является пользовательским элементом управления. Данные, которые оно получает (например, ItemTypes в таблице), поступают со страницы, которая содержит этот пользовательский элемент управления, и имеет свой набор DataContext.
Ответ №3:
Я бы сказал, просто не устанавливайте DataContext
на Grid
. Вместо этого привяжите каждый элемент по отдельности. Сложно давать дальнейшие советы, если вы не предоставите дополнительную информацию — в частности, о вашей виртуальной машине.
Комментарии:
1. Сетка с ее DataContext, установленным в ItemTypes (код XAML, который я опубликовал), является пользовательским элементом управления. В нем есть типы элементов, исходящие из ViewModel, на которые настроено содержащееся в нем окно. Вы все еще думаете, что установка каждого элемента обязательна?