2012-09-04 28 views
1

我使用Caliburn Micro和Reactive Extensions開發了Windows Phone 7應用程序。ListBox中錯誤的項目選擇(Windows Phone,Caliburn.Micro,Rx)

的應用程序有一個ListBox控件的頁面:

<Grid x:Name="ContentPanel" 
      Grid.Row="1" 
      Margin="12,0,12,0"> 
     <ListBox ItemsSource="{Binding Items}"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <Views:ItemView Margin="0,12,0,0" /> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 
</Grid> 

我使用的下一個ItemView作爲DataTemplate

<UserControl ...> 
    <Grid x:Name="LayoutRoot" 
      cal:Message.Attach="[Event Tap] = [Action SelectItem]"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="Auto" /> 
     </Grid.ColumnDefinitions> 

     <TextBlock Grid.Column="0" 
        Style="{StaticResource PhoneTextLargeStyle}" 
        Text="{Binding Name}" 
        TextWrapping="Wrap" /> 

     <TextBlock Grid.Column="1" 
        Foreground="{StaticResource PhoneDisabledBrush}" 
        Style="{StaticResource PhoneTextLargeStyle}" 
        Text="{Binding Id}" /> 
    </Grid> 
</UserControl> 

和相應的ItemViewModel看起來是這樣的:

public class ItemViewModel 
{ 
    private readonly INavigationService _navigationService; 

    public int Id { get; private set; } 

    public string Name { get; private set; } 

    public ItemViewModel(Item item) 
    { 
     Id = item.Id; 
     Name = item.Name; 

     _navigationService = IoC.Get<INavigationService>(); 
    } 

    public void SelectItem() 
    { 
     _navigationService.UriFor<MainViewModel>() 
      .WithParam(x => x.Id, Id) 
      .Navigate(); 
     } 
    } 
} 

ListBox填充項目:

public class ListViewModel : Screen 
{ 
    private readonly IItemsManager _itemsManager; 

    private List<ItemViewModel> _items; 

    public List<ItemViewModel> Items 
    { 
     get { return _items; } 
     private set 
     { 
      _items = value; 
      NotifyOfPropertyChange(() => Items); 
     } 
    } 

    public ListViewModel(IItemsManager itemsManager) 
    { 
     _itemsManager = itemsManager; 
    } 

    protected override void OnViewReady(object view) 
    { 
     base.OnViewReady(view);   

     Items = null; 

     var list = new List<ItemViewModel>(); 

     _itemsManager.GetAll() 
      .SubscribeOn(ThreadPoolScheduler.Instance) 
      .ObserveOnDispatcher() 
      .Subscribe((item) => list.Add(new ItemViewModel(item)), 
       (ex) => Debug.WriteLine("Error: " + ex.Message), 
       () => 
        { 
         Items = list; 
         Debug.WriteLine("Completed")); 
        } 
    } 
} 

而這裏的問題開始。

_itemsManager正確返回所有項目。所有項目都正確顯示在ListBox。有〜150件物品。

當我點擊一個項目然後SelectItem方法在相應的ItemViewModel必須被調用。對於ListBox中的前10-20項,所有工作都可以正常工作。但是對於所有的下一個項目SelectItem方法被稱爲絕對不正確的ItemViewModel。例如,我點擊物品34,SelectItem爲物品2調用方法,我點擊45 - 爲物品23調用方法,依此類推。項目之間不存在依賴關係。

我已經在尋找bug。可能是什麼問題?

回答

1

該解決方案在閱讀Caliburn.Micro的the discussion forumthe page in documentation後發現。 所有問題都是因爲Caliburn.Micro的公約。

爲了解決我添加到DataTempalate下一個代碼的問題:cal:View.Model={Binding}。現在,隨着ListBox頁面的部分看起來像這樣:

<Grid x:Name="ContentPanel" 
     Grid.Row="1" 
     Margin="12,0,12,0"> 
    <ListBox ItemsSource="{Binding Items}"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <Views:ItemView Margin="0,12,0,0" cal:View.Model={Binding}/> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
</Grid> 

我認爲這不是一個完美的答案。所以如果有人能提供更好的答案和解釋,我會很高興。

相關問題