Медленное переключение между представлениями (представления содержат сетку данных со многими элементами) - PullRequest
0 голосов
/ 09 августа 2011

Я использую Caliburn Micro & Fluent Ribbon в своем приложении WPF на основе .NET 4.0.Моя проблема в том, что смена взглядов происходит слишком медленно.Я думаю, что знаю корень этой проблемы.

Но я не знаю, как решить.Итак, сначала я опишу дизайн моего приложения.

Оболочка является окном WPF и содержит Fluent Ribbon.Menu с элементами RibbonTabItem.Если пользователь нажимает на элемент вкладки в оболочке, загружается новый вид.

Вот XAML вида:

    <StackPanel Grid.Row="0">
        <Fluent:Ribbon>
            <Fluent:Ribbon.Menu>

                <Fluent:Backstage>
                    <Fluent:BackstageTabControl>
                        <Fluent:BackstageTabItem Header="Open"/>
                        <Fluent:BackstageTabItem Header="Close"/>
                    </Fluent:BackstageTabControl>
                </Fluent:Backstage>

            </Fluent:Ribbon.Menu>

            <!--Tabs-->
            <Fluent:RibbonTabItem Micro:Message.Attach="[PreviewMouseLeftButtonDown]=[Action ShowView1()]"/>
    <Fluent:RibbonTabItem Micro:Message.Attach="[PreviewMouseLeftButtonDown]=[Action ShowView2()]"/>
    <Fluent:RibbonTabItem Micro:Message.Attach="[PreviewMouseLeftButtonDown]=[Action ShowViewN()]"/>

        </Fluent:Ribbon>

    </StackPanel>

    <Grid Grid.Row="1">
        <ContentControl x:Name="ActiveItem" />
    </Grid>
</Grid>

Класс модели ShellView:

namespace T_TOOL.ViewModels
{

    public interface IShellViewModel{}

    [Export(typeof(IShellViewModel))]
    public class ShellViewModel :Conductor<IScreen>.Collection.OneActive,
        IShellViewModel, 
        IPartImportsSatisfiedNotification
    {

        public void ShowView1()
        {
            var screen = IoC.Get<IShowView1();
            ActivateItem(screen);
        }

        public void ShowView2()
        {
            var screen = IoC.Get<IShowView2();
            ActivateItem(screen);
        }

//...
        public void ShowViewN()
        {
            var screen = IoC.Get<IShowViewN();
            ActivateItem(screen);
        }

    }
}

ViewModel1, ViewModel2, ... ViewModelN содержит только элементы управления DataGrid.В элементе управления Datagrid я связываю тип свойства ICollectionView из модели представления.

Это свойство содержит 18 000 - 25 000 элементов.Я думаю, что это корень проблемы, почему изменения между представлениями происходят медленно.Я использую DataGrid Control из Extended WPF Toolkit.

Я устанавливаю свойства EnableRowVirtualization и EnableColumnVirtualization для DataGrid в значение true.Но это не помогает.

Вот код XAML View ViewModel1:

    <Style x:Key="MainView_CallsDataGrid" TargetType="{x:Type Controls:DataGrid}" 
           BasedOn="{StaticResource MainView_FontBaseStyle}">
        <Setter Property="AutoGenerateColumns" Value="False"/>
        <Setter Property="VerticalScrollBarVisibility" Value="Visible"/>
        <Setter Property="HorizontalScrollBarVisibility" Value="Visible"/>
        <Setter Property="VerticalAlignment" Value="Stretch"/>
        <Setter Property="HorizontalAlignment" Value="Stretch"/>
        <Setter Property="Margin" Value="4,15,4,15"/>
        <Setter Property="EnableRowVirtualization" Value="True"/>
        <Setter Property= "EnableColumnVirtualization" Value="True"/>
    </Style>

        <Controls:DataGrid.Columns>

            <Controls:DataGridTextColumn IsReadOnly="True"
                                         CellStyle="{StaticResource MainView_CallsDataGrid_CellStyle}"
                                         Binding="{Binding Path=Number}"
                                         Header="Cell phone No"/>

            <Controls:DataGridTextColumn IsReadOnly="True"
                                         CellStyle="{StaticResource MainView_CallsDataGrid_CellStyle}"
                                         Binding="{Binding Path=CallType}"
                                         Header="Call type"/>

            <Controls:DataGridTextColumn IsReadOnly="True"
                                         CellStyle="{StaticResource MainView_CallsDataGrid_CellStyle}"
                                         Binding="{Binding Path=Dt}"
                                         Header="Date / Time"/>


            <Controls:DataGridTextColumn IsReadOnly="True"
                                         CellStyle="{StaticResource MainView_CallsDataGrid_CellStyle}"
                                         Binding="{Binding Path=CallingNumber}"
                                         Header="Calling Number"/>


            <Controls:DataGridTextColumn IsReadOnly="True"
                                         CellStyle="{StaticResource MainView_CallsDataGrid_CellStyle}"
                                         Binding="{Binding Path=VoiceNetwork}"
                                         Header="Voice network"/>

            <Controls:DataGridTextColumn IsReadOnly="True"
                                         CellStyle="{StaticResource MainView_CallsDataGrid_CellStyle}"
                                         Binding="{Binding Path=Type}"
                                         Header="Type"/>

            <Controls:DataGridTextColumn IsReadOnly="True"
                                         CellStyle="{StaticResource MainView_CallsDataGrid_CellStyle}"
                                         Binding="{Binding Path=TalkTime}"
                                         Header="Talk time"/>

            <Controls:DataGridTextColumn IsReadOnly="True"
                                         CellStyle="{StaticResource MainView_CallsDataGrid_CellStyle}"
                                         Binding="{Binding Path=Price}"
                                         Header="Price"/>

        </Controls:DataGrid.Columns>

код из класса ViewModel1:

        public ICollectionView CallsView
        {
            get
            {
                return _callsView;
            }
            set
            {
                _callsView = value;
                NotifyOfPropertyChange(() => CallsView);
            }
        }

//... Init CallsView property from List<T> property

       CallsView = CollectionViewSource.GetDefaultView(List<T>);
       FilterCalls();
       CallsView.Refresh();

//Filter method
        private void FilterCalls()
        {
            if (CallsView != null)
            {
                CallsView.Filter = new Predicate<object>(FilterOut);
                CallsView.Refresh();
            }
        }

Мое мнение верно?Переключение между представлениями происходит медленно, потому что сетка данных содержит много строк?Или проблема заключается в том, что я связываюсь с типом свойства элемента управления DataGrid объекта ICollectionView?

Спасибо за ваши мнения, предложения и отзывы.

Снимок экрана http://i51.tinypic.com/2mzyzh4.jpg

1 Ответ

0 голосов
/ 10 августа 2011

Я не уверен, если вкладки ленты совпадают с вкладками TabControl, но TabControl уничтожает его элементы TabItems, когда они не видны.Это приводит к тому, что каждый TabItem будет перерисован при переключении на вкладку, а TabItem с большим количеством элементов управления будет занимать заметное количество времени для перерисовки.

У меня была похожая проблема с использованием TabControlгде переключение вкладок перерисовало бы всю вкладку, и это вызвало очень медленное переключение.Я закончил тем, что использовал код, показанный здесь , который расширяет TabControl и предотвращает уничтожение его дочерних элементов при переключении вкладок.Возможно, вы можете сделать что-то похожее с вкладками ленты

...