这是我的MainPage.xaml: -
<UserControl x:Class="SilverlightPlainWCF.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" xmlns:my="clr-namespace:SilverlightPlainWCF.CustomersServiceRef" Loaded="UserControl_Loaded">
<UserControl.Resources>
<CollectionViewSource x:Key="customerViewSource" d:DesignSource="{d:DesignInstance my:Customer, CreateList=True}" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<sdk:DataGrid AutoGenerateColumns="False" Height="426" HorizontalAlignment="Left" ItemsSource="{Binding}" Margin="12,12,0,0" Name="customerDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" VerticalAlignment="Top" Width="776">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn x:Name="addressColumn" Binding="{Binding Path=Address}" Header="Address" Width="SizeToHeader" />
<sdk:DataGridTextColumn x:Name="cityColumn" Binding="{Binding Path=City}" Header="City" Width="SizeToHeader" />
<sdk:DataGridTextColumn x:Name="companyNameColumn" Binding="{Binding Path=CompanyName}" Header="Company Name" Width="SizeToHeader" />
<sdk:DataGridTextColumn x:Name="contactNameColumn" Binding="{Binding Path=ContactName}" Header="Contact Name" Width="SizeToHeader" />
<sdk:DataGridTextColumn x:Name="contactTitleColumn" Binding="{Binding Path=ContactTitle}" Header="Contact Title" Width="SizeToHeader" />
<sdk:DataGridTextColumn x:Name="countryColumn" Binding="{Binding Path=Country}" Header="Country" Width="SizeToHeader" />
<sdk:DataGridTextColumn x:Name="customerIDColumn" Binding="{Binding Path=CustomerID}" Header="Customer ID" Width="SizeToHeader" />
<sdk:DataGridTextColumn x:Name="faxColumn" Binding="{Binding Path=Fax}" Header="Fax" Width="SizeToHeader" />
<sdk:DataGridTextColumn x:Name="phoneColumn" Binding="{Binding Path=Phone}" Header="Phone" Width="SizeToHeader" />
<sdk:DataGridTextColumn x:Name="postalCodeColumn" Binding="{Binding Path=PostalCode}" Header="Postal Code" Width="SizeToHeader" />
<sdk:DataGridTextColumn x:Name="regionColumn" Binding="{Binding Path=Region}" Header="Region" Width="SizeToHeader" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</Grid>
</UserControl>
这是我的MainPage.xaml.cs: -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using SilverlightPlainWCF.CustomersServiceRef;
using System.Diagnostics;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace SilverlightPlainWCF
{
public partial class MainPage : UserControl, INotifyPropertyChanged
{
public MainPage()
{
InitializeComponent();
this.DataContext = Customers;
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
public ObservableCollection<Customer> customers;
public ObservableCollection<Customer> Customers
{
get { return customers; }
set
{
customers = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Customers"));
}
}
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
CustomersServiceClient objCustomersServiceClient = new CustomersServiceClient();
objCustomersServiceClient.GetAllCustomersCompleted += (s, res) =>
{
if (res.Error == null)
{
Customers = new ObservableCollection<Customer>(res.Result);
}
else
{
MessageBox.Show(res.Error.Message);
}
};
objCustomersServiceClient.GetAllCustomersAsync();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
// Do not load your data at design time.
// if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
// {
// //Load your data here and assign the result to the CollectionViewSource.
// System.Windows.Data.CollectionViewSource myCollectionViewSource = (System.Windows.Data.CollectionViewSource)this.Resources["Resource Key for CollectionViewSource"];
// myCollectionViewSource.Source = your data
// }
// Do not load your data at design time.
// if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
// {
// //Load your data here and assign the result to the CollectionViewSource.
// System.Windows.Data.CollectionViewSource myCollectionViewSource = (System.Windows.Data.CollectionViewSource)this.Resources["Resource Key for CollectionViewSource"];
// myCollectionViewSource.Source = your data
// }
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
如果我只是移动线: -
this.DataContext = Customers;
从构造函数到这里: -
if (res.Error == null)
{
Customers = new ObservableCollection<Customer>(res.Result);
this.DataContext = Customers;
}
它工作正常,我得到所有数据。可能是什么问题。有人能帮助我吗?
答案 0 :(得分:2)
当你把它放在构造函数中时它不起作用的原因是那时customers
字段中还没有任何值。
只有在触发MainPage_Loaded
时才会获得该值,由于XAML中的以下行,这不会发生:
Loaded="UserControl_Loaded"
这将执行UserControl_Loaded
而不是MainPage_Loaded
。您可以做的是从MainPage_Loaded
拨打UserControl_Loaded
,这可能不是您打算做的。因此,在这种情况下,您应该将XAML更改为:
Loaded="MainPage_Loaded"
您可以完全删除UserControl_Loaded
,因为您不再使用它了。
至于将结果分配给DataGrid,您实际上可以通过将结果直接分配到DataContext
而不是通过Customers
属性来直接执行。
但如果您坚持将其分配给Customers
属性并相应地更新DataGrid,那么下一个最简单的解决方案是在Customers
set方法的某处包含以下行:
DataContext = value;
如果你真的,真的坚持DataGrid应该在触发PropertyChanged
事件时自行更新,而不需要编码DataContext = Customers
行,那么你想要的是数据绑定。通过将DataContext
属性绑定到您的Customers
属性,DataGrid将在收到PropertyChanged
事件时更新。
要在XAML中声明数据绑定,您需要为UserControl
标记指定一个名称。然后你将绑定分配给DataContext
,就像这一行:
DataContext="{Binding Path=Customers, ElementName=theUserControlName}"
如果我是你,而不是必须实现INotifyPropertyChanged
界面,我会改为使用Dependency Properties。将您的示例转换为使用Dependency Property,我会:
public static DependencyProperty CustomersProperty =
DependencyProperty.Register("Customers", typeof(ObservableCollection<Customer>), typeof(MainPage), null);
public ObservableCollection<Customer> Customers
{
get { return (ObservableCollection<Customer>) GetValue(CustomersProperty); }
set { SetValue(CustomersProperty, value); }
}
就是这样,财产变更通知将由框架处理。
答案 1 :(得分:0)
我认为问题是在构造函数中你没有这一行:
Customers = new ObservableCollection<Customer>(res.Result);
在尝试将DataContext设置为该值之前。