1

CaliburnMicroとReactiveExtensionsを使用してWindowsPhone7用のアプリを開発しています。

アプリには、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呼び出す必要があります。そして、すべてがの最初の10〜20個のアイテムで正常に機能しListBoxます。しかし、次のすべての項目について、SelectItemメソッドは絶対に正しく呼び出されませんItemViewModel。たとえば、アイテム34をタップすると、SelectItemメソッドがアイテム2に対して呼び出され、45をタップします。メソッドはアイテム23に対して呼び出され、以下同様に続きます。また、アイテム間に依存関係はありません。

私はすでにバグを探して頭を悩ませています。何が問題になるのでしょうか?

4

1 に答える 1

1

解決策は、Caliburn.Microのドキュメントのディスカッションフォーラムとページを読んだ後に見つかりました。すべての問題は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>

完璧な答えではないと思います。ですから、誰かがもっと良い答えと説明を提供してくれたら嬉しいです。

于 2012-09-05T07:01:50.453 に答える