Silverlight 4.0 PropertyChanged始终为空
这是我的主页。xaml:-Silverlight 4.0 PropertyChanged始终为空,silverlight-4.0,Silverlight 4.0,这是我的主页。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
<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>
从构造函数到此处:-
if (res.Error == null)
{
Customers = new ObservableCollection<Customer>(res.Result);
this.DataContext = Customers;
}
if(res.Error==null)
{
客户=新的可观察收集(res.Result);
this.DataContext=客户;
}
它工作正常,我得到了所有的数据。有什么问题吗。有人能帮我吗?我认为问题在于,在构造函数中,您没有这一行:
Customers = new ObservableCollection<Customer>(res.Result);
DataContext="{Binding Path=Customers, ElementName=theUserControlName}"
Customers=新的可观察收集(res.Result);
在您尝试将DataContext设置为该值之前。将其放入构造函数时,它不起作用的原因是此时
customers
字段中还没有任何值
只有在触发MainPage_Loaded
时,才会获得该值,这不会发生,因为XAML中有以下行:
Loaded="UserControl_Loaded"
这将执行UserControl\u加载的
,而不是MainPage\u加载的
。您可以从UserControl\u-Loaded
调用MainPage\u-Loaded
,这可能不是您想要做的。因此,在这种情况下,您应该将XAML改为:
Loaded="MainPage_Loaded"
您可以完全删除加载的UserControl\u
,因为您不再使用它了
至于将结果分配给DataGrid,实际上可以直接将结果分配给DataContext
,而不是通过Customers
属性
但是如果您坚持将其分配给Customers
属性,并相应地更新数据网格,那么下一个最简单的解决方案是在Customers
set方法中的某个位置包含以下行:
DataContext = value;
如果您真的、真的坚持在触发PropertyChanged
事件时DataGrid应该自我更新,而不必对DataContext=Customers
行进行编码,那么您需要的是数据绑定。通过将DataContext
属性绑定到Customers
属性,DataGrid将在收到PropertyChanged
事件时更新
要在XAML中声明数据绑定,需要为UserControl
标记指定一个名称。然后将绑定分配给DataContext
,如下所示:
Customers = new ObservableCollection<Customer>(res.Result);
DataContext="{Binding Path=Customers, ElementName=theUserControlName}"
如果我是你,我就不用实现INotifyPropertyChanged
接口,而是使用。将您的示例转换为使用Dependency属性,我将:
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); }
}
公共静态从属属性CustomerProperty=
DependencyProperty.Register(“客户”、typeof(ObservableCollection)、typeof(主页)、null);
公开收集客户
{
get{return(ObservableCollection)GetValue(CustomerProperty);}
set{SetValue(CustomerProperty,value);}
}
仅此而已,属性更改通知将由框架处理。-我已经使用
INotifyPropertyChanged
在ObservableCollection
的内容更改后立即更新网格。我已经解决了这个错误,只需设置this.DataContext=this
而不是this.DataContext=Customers
,并根据更改的DataGrid绑定到{binding Path=Customers}
而不是{binding}
@Nitesh:当ObservableCollection
的内容更改时,您不需要实现INotifyPropertyChanged
来更新网格,这是由ObservableCollection
本身自动完成的。您实现了INotifyPropertyChanged
,让网格知道您为ObservableCollection
分配了一个全新的实例。是的,您还可以设置this.DataContext=this,这是另一种方法。如果你能理解为什么它是这样工作的,那就更好了。-谢谢你的好意。现在我的概念越来越清晰了。然而,几乎没有更多的疑问。我希望你不介意回答他们。1) 当我们从UI(数据网格)添加新行时,该行是否会添加到代码隐藏的可观测集合中?2) 我应该创建一个dependencProperty
还是实现INotifyPropertyChanged
?哪种做法最好?INotifyPropertyChanged
不是更有效吗?@Nitesh,回答你的问题:1)对不起,我不是很确定。但是我非常确定,如果您在代码隐藏的observateCollection
中添加新行,那么DataGrid
将相应地更新。2) 我不能说哪一个是最好的实践,但是对于WPF/Silverlight相关的东西,Microsoft正在将它们的大多数属性实现为依赖属性,通过这样做,它自动提供更改通知、绑定支持等。这说明了什么吗?:)-是的,它说了一切,我已经投票并检查了你的答案:)