У меня огромные проблемы с ComboBoxes в сетке данных. И мне действительно нужна помощь, я думаю, я запутался объемом исследований и тем, что я пробовал. Это действительно должно быть просто, поэтому я, должно быть, что-то упускаю.
УПРОЩЕННАЯ ПРОБЛЕМА
Я использую CollectionViewSource в xaml, C # устанавливает источник этого CollectionViewSource на ObservableCollection в классе, который является текстом страницы. Добавление элементов в коллекцию не обновляет столбец DataGridComboBox, в котором отображается источник представления. См. Ниже строку для более подробной информации.
ОБЗОР
У меня есть страница WPF с сеткой данных. Страница имеет контекст данных, установленный для модели представления. ViewModel содержит две наблюдаемые коллекции. Один для оборудования и один для локаций. У каждого снаряжения есть локация. Они заполняются из базы данных EF с первым кодом, но я считаю, что эта проблема выше этого уровня.
Сетка данных представляет собой одну строку на каждое оборудование. Столбец Location должен быть выбираемым комбинированным списком, который позволяет пользователю изменять Location.
Единственный способ, которым я мог вообще заполнить поле со списком местоположений, - это привязать его к отдельному источнику представления коллекции.
ПРОБЛЕМА
Кажется, что если событие загрузки страницы происходит до того, как ViewModel заполняет ObservableCollection, тогда locationVwSrc будет пустым, и событие изменения свойства не заставит это измениться.
КРАТКАЯ ВЕРСИЯ РЕАЛИЗАЦИИ. На странице есть коллекция viewSource, определенная в xaml.
Loaded="Page_Loaded"
Title="EquipRegPage">
<Page.Resources>
<CollectionViewSource x:Key="locationsVwSrc"/>
</Page.Resources>
Сетка данных определяется с помощью xaml.
<DataGrid x:Name="equipsDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" Margin="10,10,-118,59"
ItemsSource="{Binding Equips}" EnableRowVirtualization="True" AutoGenerateColumns="False">
Столбец combobox, определенный в xaml
<DataGridComboBoxColumn x:Name="locationColumn" Width="Auto" MaxWidth="200" Header="Location"
ItemsSource="{Binding Source={StaticResource locationsVwSrc}, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name"
SelectedValueBinding="{Binding Location}"
Контекст страницы установлен на модель представления
public partial class EquipRegPage : Page
{
EquipRegVm viewModel = new EquipRegVm();
public EquipRegPage()
{
InitializeComponent();
this.DataContext = viewModel;
}
Загруженное событие, устанавливающее контекст
private void Page_Loaded(object sender, RoutedEventArgs e)
{
// Locations View Source
System.Windows.Data.CollectionViewSource locationViewSource =
((System.Windows.Data.CollectionViewSource)(this.FindResource("locationsVwSrc")));
locationViewSource.Source = viewModel.Locations;
// Above does not work if the viewmodel populates these after this call, only works if its populated prior.
//TODO inotifypropertychanged not correct? This occurs before the viewmodels loads, and doesn't display.
// Therefore notify property changes aren't working.
// Using this as cheat instead instead works, i beleive due to this only setting the source when its full
//viewModel.Db.Locations.Load();
//locationViewSource.Source = viewModel.Db.Locations.Local;
//locationViewSource.View.Refresh();
}
Класс ViewModel и как он загружается
public class EquipRegVm : DbWrap, INotifyPropertyChanged
{
/// <summary>
/// Event triggered by changes to properties. This notifys the WPF UI above which then
/// makes a binding to the UI.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Notify Property Changed Event Trigger
/// </summary>
/// <param name="propertyName">Name of the property changed. Must match the binding path of the XAML.</param>
void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public ObservableCollection<Equip> Equips { get; set; }
public ObservableCollection<Location> Locations { get; set; }
public EquipRegVm() : base()
{
Load();
}
/// <summary>
/// Load the data from the Model.
/// </summary>
public async void Load() //TODO async an issue?
{
// EQUIPMENT
ObservableCollection<Equip> eqList = new ObservableCollection<Equip>();
var eqs = await (from eq in Db.Equips
orderby eq.Tag
select eq).ToListAsync();
foreach(var eq in eqs)
{
eqList.Add(eq);
}
Equips = eqList;
RaisePropertyChanged("Equips");
// LOCATIONS
ObservableCollection<Location> locList = new ObservableCollection<Location>();
var locs = await (from l in Db.Locations
orderby l.Name
select l).ToListAsync();
foreach (var l in locs)
{
locList.Add(l);
}
Locations = locList;
RaisePropertyChanged("Locations");
}
}