I use Caliburn Micro & Fluent Ribbon in my WPF app based on .NET 4.0. My problem is that change between views is too slow. I think that I know root of this problem.
But I don’t how to solve. So first I describe design of my app.
Shell is WPF window and it contains Fluent Ribbon.Menu with RibbonTabItem items. If user click on tab item in shell is loaded new view.
Here is XAML of view:
<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 model class:
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 contains only DataGrid controls. On Datagrid control I bind property type of ICollectionView from view model.
This property contains 18 000 - 25 000 items. I think this is root of problem why is change between Views is slow. I use DataGrid Control from Extended WPF Toolkit.
I set EnableRowVirtualization and EnableColumnVirtualization properties of DataGrid on true. But it doesn’t help.
Here is View XAML code of ViewModel1:
<开发者_Python百科;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>
code from ViewModel1 class:
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();
}
}
My opinion is correct? Switch betweens views is slow because datagrid contains many rows? Or problem is that I bind on DataGrid control property type of ICollectionView?
Thank you for your opinions, suggestions and feedback.
Here is screen shot.
I'm not positive if the Ribbon tabs are the same as a TabControl tabs, but a TabControl destorys it's TabItems when they're not visible. This causes each TabItem to get re-drawn when you switch to the tab, and a TabItem with a large number of controls will take a noticable amount of time to get redrawn.
I had a similar problem using a TabControl where switching tabs would re-draw the entire tab and it caused switching to be really slow. I ended up using the code shown here that extends the TabControl and prevents it from destorying it's children when switching tabs. Perhaps you can do something similiar with the Ribbon tabs
精彩评论