Сбой приложения при смене вкладок, содержащих списки со списком элементов - PullRequest
0 голосов
/ 01 декабря 2008

У меня есть WPF TabControl с двумя TabItems. Каждый TabItem содержит ListBox с отдельной ObservableCollection в качестве его ItemsSource. Каждый ListBox имеет свой шаблон ItemTemplate.

Независимо от того, какой TabItem я установил для выбора при запуске, эта вкладка будет отображаться нормально, но при нажатии на другую вкладку приложение вылетает с ошибкой «Исключение было вызвано целью вызова», указывающей DataTemplate для вкладки, на которую я переключаюсь.

Если я удаляю ItemTemplate из ListBox на вкладке, которую я пытаюсь переключить (и использую DisplayMemberPath), все работает нормально.

Однако, если я использую DataTemplate, будь то встроенный или в качестве StaticResource или DynamicResource, это вызывает сбой при переключении вкладок.

Есть идеи? Псевдокод следует:


<Window x:Class="Example.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:objects="clr-namespace:Example.CoreObjects"
    xmlns:controls="clr-namespace:Example.Controls"
    >
<Window.Resources>
    <DataTemplate x:Key="ItemTemplateOne">
        <controls:CustomControlOne />
    </DataTemplate>
    <DataTemplate x:Key="ItemTemplateTwo">
        <controls:CustomControlTwo />
    </DataTemplate>
</Window.Resources>
<Grid>
    <TabControl Name="tabControl1">
        <TabItem Header="TabOne">
            <Grid>
                <ScrollViewer>
                    <ListBox Name="ListBoxOne" 
                             ItemsSource="{Binding}"
                             ItemTemplate="{StaticResource ItemTemplateOne}"
                             >
                        <ListBox.ItemsPanel>
                            <ItemsPanelTemplate>
                                <WrapPanel /> 
                            </ItemsPanelTemplate>
                        </ListBox.ItemsPanel>
                    </ListBox>
                </ScrollViewer>
            </Grid>
        </TabItem>
        <TabItem Header="TabTwo">
            <Grid>
                <ScrollViewer>
                    <ListBox Name="ListBoxTwo" 
                             ItemsSource="{Binding}"
                             ItemTemplate="{StaticResource ItemTemplateTwo}"
                             >
                        <ListBox.ItemsPanel>
                            <ItemsPanelTemplate>
                                <WrapPanel />
                            </ItemsPanelTemplate>
                        </ListBox.ItemsPanel>
                    </ListBox>
                </ScrollViewer>
            </Grid>
        </TabItem>
    </TabControl>
</Grid>

public Window1 () { InitializeComponent ();

ListBoxOne.DataContext = ObservableCollectionOne;
CollectionViewOne = CollectionViewSource.GetDefaultView(ObservableCollectionOne);
CollectionViewOne.SortDescriptions.Add(new SortDescription("SortProperty", ListSortDirection.Descending));

ListBoxTwo.DataContext = ObservableCollectionTwo;
CollectionViewTwo = CollectionViewSource.GetDefaultView(ObservableCollectionTwo);
CollectionViewTwo.SortDescriptions.Add(new SortDescription("SortProperty", ListSortDirection.Descending));

}

Ответы [ 2 ]

1 голос
/ 01 декабря 2008

Независимо от того, какой TabItem я установил, чтобы выбрать при запуске, эта вкладка будет отображаться нормально, но когда я нажимаю на другую вкладку, приложение вылетает с ошибкой «Исключение было вызвано целью вызова», указывающей на шаблон данных для вкладки, на которую я переключаюсь.

Включите исключения первого шанса, чтобы вы могли найти действительное исключение вместо перенесенного внешнего исключения - что будет не так, будет намного понятнее.

0 голосов
/ 01 декабря 2008

Я думаю, что проблема в том, что оба ListBox's ItemSource = "{Binding}". Я думаю, что это говорит о привязке к DataContext окна, но в коде вы устанавливаете отдельно.

Попробуйте объявить CollectionViewSource (или два, если вы хотите разные сортировки между ListBoxes) в вашем Window.Resources. Установите свой Observablecollection в качестве источника CollectionViewSource.

Затем в ваших ListBoxes сделайте привязку к источнику CollectionView.

Если это не сработает, вы можете попробовать поместить каждый ListBox и связанные с ним ресурсы данных в отдельные элементы UserControls.

...