我試圖加載一個列表框,列出了正在從OData Web服務中拉出的項目。數據抓取工作正常,我得到的項目列表。該列表框實際上工作並顯示項目,而不是每次啓動應用程序時...由於需要異步拉取數據,有時候列表框會在數據返回之前加載。當它給我一個單一的'空'項目列表,以表明數據仍在加載。幾秒鐘後,數據已經加載,我爲列表引發一個PropertyChanged事件。我在列表屬性觸發器中的斷點,當我檢查列表包含正確的項目。但是列表框不顯示新項目,只顯示舊的'空'項目。對我來說,看起來奇怪的是,xaml明確要求列表,但不刷新新項目的佈局。Silverlight列表框不刷新列表
首先初始化ViewModel的代碼。 ModelReferenceMap實現INotifyPropertyChanged,因此應該在OnPropertyChanged(「Areas」);被調用(這會觸發從屬性中獲取列表,但不會更新視圖)。
public ModelReferenceMap(Uri serviceURI)
{
// Try initialising these lists to a non null but empty list
// in the hope it will stop the lists breaking when the service
// is a little bit slow...
areas = new List<ModelReferenceItem> { new ModelReferenceItem(null) };
// This is a ServiceReference entity context which will retrieve the data from the OData service
context = new LiveEntities(serviceURI);
// SendingRequest adds credentials for the web service
context.SendingRequest += context_SendingRequest;
// The query to retrieve the items
var areaQuery = from i in context.MigrationItems where i.FusionPTID == 0 && i.Type == "AreaType" orderby i.Name select i;
// On completion this asynccallback is called
AsyncCallback ac = iasyncResult =>
{
// Populates the List with the data items
areas = (from i in ((DataServiceQuery<MigrationItem>) areaQuery).EndExecute(iasyncResult)
select new ModelReferenceItem(i)).ToList();
foreach (ModelReferenceItem area in areas)
{
if (selectedArea == null)
selectedArea = area;
area.PropertyChanged += referenceItem_PropertyChanged;
}
// The Xaml Listbox has its ItemsSource bound to the Areas property. This should trigger a refresh of the listbox contents shouldn't it?
OnPropertyChanged("Areas");
OnPropertyChanged("SelectedArea");
};
// Start the query
((DataServiceQuery<MigrationItem>)areaQuery).BeginExecute(ac, null);
}
現在的XAML。請注意,列表框的DataContext是ReferenceMap(我的主ViewModel上的一個屬性,它暴露了ModelReferenceMap的單例實例)。然後我將ItemsSource綁定到區域。
<ListBox Grid.Row="0" DataContext="{Binding ReferenceMap}" ItemsSource="{Binding Areas}" SelectedItem="{Binding SelectedArea, Mode=TwoWay}" HorizontalAlignment="Stretch" Margin="3" Name="listBoxFusionAreas" VerticalAlignment="Stretch">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Background="{Binding CompleteStatusColour}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock FontSize="12" Text="{Binding Name}" />
<TextBlock Grid.Column="1" FontSize="12" Text="{Binding Count}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Areas屬性觸發正確表明綁定正在工作。只有在服務數據已被檢索(即只有一次)之後請求區域時,該列表完美地工作。然而,如果Areas屬性在服務數據返回之前觸發(即使用單個'空'項目),它將在OnPropertyChanged(「Areas」)期間再次觸發;與全套項目打電話,只是這次列表仍然只顯示原來的'空'項目。
我在做什麼錯?
我給在INoifyCollectionChanged事件一個鏡頭,但是當服務最終返回數據時整個列表被替換。不是添加和刪除單個項目的情況。如果它不能立即工作,我會嘗試清除和添加,而不是替換現有的列表... – 2012-03-02 07:10:56
似乎已經完成了這個伎倆。地區現在是ObservableCollection。當數據返回時,我調用areas.Clear();然後areas.Add();在處理單個項目時,即添加事件處理程序。爲快速響應歡呼。 –
2012-03-02 07:38:06
p.s.該死的確定我在幾年前遇到了這個......但我想這就是當你在iOS上開發18個月時會發生什麼情況:( – 2012-03-02 07:38:52