0

当一个 Windows Phone 7 应用程序打开一个视图时,按照一定的业务顺序来创建。就构造函数和事件而言,我发现这个顺序是正确的:

  1. Constructor
  2. OnNavigatedTo
  3. OnLoaded

但是,我需要在加载基本视图(背景、其他元素等)后将a 数据绑定List到 a 。ListBox所以在我开始数据绑定之前,我需要知道何时以及如何知道视图已加载。

我试图在OnLoaded-event 上执行此操作,但似乎如果我在这里进行数据绑定 - 并且在它遍历这些元素之后 - 它们似乎还不存在(VisualTreeHelper-class 似乎找不到节点)。所以如你所见,我被困住了。

任何帮助将不胜感激。

编辑:根据要求,这里有一些关于正在发生的事情的更多信息。

MyList由一些自定义(不太复杂)对象填充,包括异步加载的图像(由delay.LowProfileImageLoader提供)和矩形。

XAML:

<ListBox x:Name="ChannelsListBox" ItemsSource="{Binding AllChannels}">
//... 
<ListBox.ItemTemplate>
    <DataTemplate>
        <Grid x:Name="ChannelTile" Margin="6,6,6,6" Tap="ChannelTile_Tap" Opacity="0.4">
            <!-- context menu goes here -->
            <Rectangle Width="136" Height="136" Fill="{StaticResource LightGrayColor}" />
            <Image Width="136" Height="136" delay:LowProfileImageLoader.UriSource="{Binding ImageUri}" />
        </Grid>
    </DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

代码隐藏:

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    UpdateApplicationBar();

    pickChannelsViewModel = new PickChannelsViewModel();
    DataContext = pickChannelsViewModel;

    if (hasUpdatedTiles)
    {
        pickChannelsViewModel.IsLoading = false; // Set by UpdateTiles()
    }
}


private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
    // This is where I would data bind the list (instead of in XAML)
    UpdateTiles(); // Traverses the list and changes opacity of "selected" items.
}

protected void UpdateTiles()
    {
        foreach (var item in ChannelsListBox.Items)
        {
            if (pickChannelsViewModel.SelectedChannels.Contains(item as Channel))
            {
                var index = ChannelsListBox.Items.IndexOf(item);

                // This returns null when databinding in codebehind, 
                // but not in XAML
                ListBoxItem currentItem = ChannelsListBox.ItemContainerGenerator.ContainerFromIndex(index) as ListBoxItem;

                if (currentItem != null && VisualTreeHelper.GetChildrenCount(currentItem) == 1)
                {
                    var OuterWrapper = VisualTreeHelper.GetChild(currentItem, 0);
                    var MiddleWrapper = VisualTreeHelper.GetChild(OuterWrapper, 0);
                    var InnerWrapper = VisualTreeHelper.GetChild(MiddleWrapper, 0);
                    Grid currentItemGrid = VisualTreeHelper.GetChild(InnerWrapper, 0) as Grid;

                    currentItemGrid.Opacity = 1.0;
                }
            }
        }
        pickChannelsViewModel.IsLoading = false;
        hasUpdatedTiles = true;
    }

这些项目本身是在内存中的(在应用程序的早期阶段从 REST 中获取),因此应该立即可用。

我试图解决的问题是这个特别视图的加载时间相当长(大约创建了 140 个这些项目,然后过滤并更改不透明度)。

4

1 回答 1

0

我相信你正在做类似的事情:

myListBox.ItemSource=myList;

设置 ListBox 的 ItemSource 后,List 中的更改应始终反映在 ListBox 中。如果 ListBox 为空,则原因必须是 List 未正确填充或Bindings在 ItemTemplate 中无效。Loaded()您应该通过在方法中插入断点来调试并确定您的 List 是否有任何项目。此外,您还没有提到您的 List 包含哪些项目,或者它在应用程序中的哪个位置填充?不完整的信息对任何人都没有帮助。

于 2012-07-09T07:14:35.420 回答