데이터 그리드의 ComboBox에 막대한 문제가 있습니다. 그리고 정말로 도움이 필요 하겠지만, 나는 연구의 양과 내가 시도한 것에 혼란스러워했다. 이것은 정말 간단해야 그래서 뭔가를 놓치고 있어야합니다.CollectionViewSource가 PropertyChanged로 업데이트되지 않습니다.
약식 문제는 XAML에서 CollectionViewSource를 사용
는 C#을 페이지의 데이터 컨텍스트입니다 클래스에 ObservableCollection에 해당 CollectionViewSource의 소스를 설정합니다. 컬렉션에 항목을 추가해도 뷰 소스를 표시하는 DataGridComboBox 열이 업데이트되지 않습니다. 자세한 내용
개요
나는 그것에 데이터 그리드와 WPF 페이지를위한 라인 아래를 참조하십시오. 페이지의 데이터 컨텍스트가 뷰 모델로 설정되어 있습니다. viewModel에는 2 개의 관찰 가능한 컬렉션이 있습니다. 하나는 장비를위한 것이고 다른 하나는 위치를위한 것입니다. 각 장비에는 위치가 있습니다. 이들은 코드 첫 번째 EF 데이터베이스에서 채워지지만이 문제는 그 수준 이상이라고 생각합니다.
Dataagrid는 장비 당 하나의 행입니다. 위치 열은 사용자가 위치를 변경할 수있는 선택 가능한 콤보 박스 여야합니다.
내가 수집 할 위치 콤보 박스를 얻는 유일한 방법은 별도의 콜렉션 뷰 소스에 바인딩하는 것입니다.
문제
페이지로드 이벤트가 ObservableCollection에 채우기 전에 뷰 모델에 발생하면 다음 locationVwSrc가 비어과 재산 변경된 경우이 변경하지 않는 것 같다.
구현 짧은 버전 페이지에 컬렉션보기 소스가 xaml에 정의되어 있습니다.
Loaded="Page_Loaded"
Title="EquipRegPage">
<Page.Resources>
<CollectionViewSource x:Key="locationsVwSrc"/>
</Page.Resources>
Dataagrid는 xaml로 정의됩니다.
<DataGrid x:Name="equipsDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" Margin="10,10,-118,59"
ItemsSource="{Binding Equips}" EnableRowVirtualization="True" AutoGenerateColumns="False">
XAML에서 정의 콤보 열
<DataGridComboBoxColumn x:Name="locationColumn" Width="Auto" MaxWidth="200" Header="Location"
ItemsSource="{Binding Source={StaticResource locationsVwSrc}, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name"
SelectedValueBinding="{Binding Location}"
컨텍스트를
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();
}
뷰 모델 클래스를 설정하고,보기 모델
public partial class EquipRegPage : Page
{
EquipRegVm viewModel = new EquipRegVm();
public EquipRegPage()
{
InitializeComponent();
this.DataContext = viewModel;
}
로드 이벤트에 설정된 페이지 문맥 어떻게로드되는지 s
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");
}
}
이것은 즉각적인 문제를 해결했습니다. 감사합니다 @AnjumSKhan. 리 캠벨 (Lee Campbell)은 내가 그에게서 더 많은 것을 배울 수있는 좋은 점을 분명히하고 있습니다. – Asvaldr
예, 그러면 문제가 해결되지만 더 많은 불필요한 코드가 추가됩니다. –
나는 당신이 더 이상 통찰력을 가지면 배우고 싶어한다는 Lee에게 동의합니다. 귀하의 솔루션에 대한 마지막 코멘트를 참조하십시오. – Asvaldr