Вы работаете с неправильным WMSDataSet
экземпляром.
Ваши привязки данных ссылаются на экземпляр, определенный в ResourceDictionary
страницы. Но на самом деле вы инициализируете второй экземпляр в обработчике событий Loaded
.
Решение состоит в том, чтобы либо создать экземпляр WMSDataSet
в коде программной части, а затем добавить его в ResourceDictionary
(или назначить его для связываемое свойство) или для получения экземпляра XAML и его инициализации. Второе решение потребовало бы, чтобы объект WMSDataSet
реализовал INotifyPropertyChanged
, чтобы внести изменения в свойство уведомления о привязке данных для обновления цели привязки. Я рекомендую выставить WMSDataSet
через DependencyProperty
:
ViewProducts.xaml.cs
public partial class ViewProducts : Page
{
public static readonly DependencyProperty WmsDataSourceProperty = DependencyProperty.Register(
"WmsDataSource",
typeof(WMSDataSet),
typeof(ViewProducts),
new PropertyMetadata(default(WMSDataSet)));
public WMSDataSet WmsDataSource
{
get => (WMSDataSet) GetValue(ViewProducts.WmsDataSourceProperty);
set => SetValue(ViewProducts.WmsDataSourceProperty, value);
}
public ViewProducts()
{
InitializeComponent();
Loaded += Page_Loaded;
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
wmsDataSet = new WMSDataSet();
ServiceReference1.Service1Client dataSvc = new ServiceReference1.Service1Client();
wmsDataSet.products.Merge(dataSvc.GetProducts());
wmsDataSet.warehouses.Merge(dataSvc.GetWarehouses());
this.WmsDataSource = wmsDataSet;
}
}
ViewProducts.xaml
<Page>
<Page.Resources>
<CollectionViewSource x:Key="ProductsViewSource" Source="{Binding RelativeSource={RelativeSource AncestorType=local:ViewProducts}, Path=WmsDataSource.products}" />
<CollectionViewSource x:Key="WarehousesViewSource" Source="{Binding RelativeSource={RelativeSource AncestorType=local:ViewProducts}, Path=WmsDataSource.warehouses}" />
</Page.Resources>
<!-- When you set the DataContext to 'ViewProducts.WmsDataSource', you can directly bind to it
using {Binding} (without specifying the Binding.Source) -->
<Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=local:ViewProducts}, Path=WmsDataSource}">
<DataGrid ItemsSource="{Binding products}">
</DataGrid>
<DataGrid ItemsSource="{Binding warehouses}">
</DataGrid>
</Grid>
</Page>
Замечания
В вашем коде есть некоторые ошибки. Вы делаете много лишнего, потому что делаете это дважды, когда последнее перезаписывает предыдущее объявление, вводит ошибки или неожиданное поведение (например, пустые элементы управления):
Конечно, уже упомянутое использование двух экземпляров WMSDataSet
. Создано в XAML:
<DataEntityTier:WMSDataSet x:Key="wMSDataSet"/>
и код программной части:
this.wMSDataSet = new WMSDataSet();
Затем вы устанавливаете DataContext
родительского элемента, чтобы игнорировать его в выражениях привязки:
<Grid DataContext="{StaticResource productsViewSource}">
<DataGrid ItemsSource="{Binding Source={StaticResource productsViewSource}}">
вместо:
<Grid DataContext="{StaticResource productsViewSource}">
<DataGrid ItemsSource="{Binding}">
Поскольку содержимое hte общий родительский Grid
(два элемента DataGrid
) не разделяют тот же контекст данных, это более запутанно, чем полезно, установить их DataContext
на общий источник . Скорее выберите следующую версию:
<Grid>
<DataGrid ItemsSource="{Binding Source={StaticResource productsViewSource}}" />
<DataGrid ItemsSource="{Binding Source={StaticResource warehousesViewSource}}" />
</Grid>
или в отрефакторной версии моего решения:
<Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=local:ViewProducts}, Path=WmsDataSource}">
<DataGrid ItemsSource="{Binding products}" />
<DataGrid ItemsSource="{Binding warehouses}" />
</Grid>
Вы также дважды подписываетесь на событие Loaded
, что приводит к тому, что обработчик события также вызывается дважды. Сначала вы подписываетесь на PageLoaded
в XAML:
<Page Loaded="Page_Loaded">
и в коде программной части:
public ViewProducts()
{
InitializeComponent();
Loaded += Page_Loaded;
}
Выберите только один.