Reputation: 31823
The Entity Framework provides Trackable Entities who have a property called ChangeTracker.State. Using this we can identify if an Entity is Deleted.
In our list we do NOT want to show Deleted entities.
Which is faster?
Method 1: Using a CollectionViewSource.Filter to Test and remove the Record
<CollectionViewSource Filter="ViewSource_Filter" />
private void ViewSource_Filter(object sender, FilterEventArgs e)
{
var _Item = e.Item as ITrackableEntity;
e.Accepted = _Item.ChangeTracker.State != ObjectState.Deleted;
}
Method 2: Adding a DataTrigger to the ItemTemplate.DataTemplate to Test and Hide the Item
<DataTemplate.Resources>
<Style TargetType="{x:Type DockPanel}">
<Style.Triggers>
<DataTrigger Binding="{Binding ChangeTracker.State}">
<DataTrigger.Value>
<entities:ObjectState>Deleted</entities:ObjectState>
</DataTrigger.Value>
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataTemplate.Resources>
Thanks.
Upvotes: 0
Views: 1475
Reputation: 19885
Assuming that there is a ItemsControl involved in this problem, I personally like the collectionview based filter.
Reasons...
Its filtering is in the hands of ViewModel. So whenever it wants to refresh the collection view it will re-filter again.
If ChangeTracker.State
property is only populated and not updated throughout the lifecycle of the UI, then the collection view will only filter once at rendering. DataTriggers on the other hand will wait for any changes to ChangeTracker.State
which may / may not happen.
Alternating Items Row styles for the ItemsControl for which this CollectionView is the applied, will not take correct effect with the data trigger, coz it will only hide the items and not adjust alternate row styles but collectionview will exclude the items beforehand itself. i.e. if alternate rows need to be of gray background then it may happen that two adjacent rows will be gray if DataTrigger is used.
DataTriggers will take effect ONLY for non-vitualized items due to which the Scrollbar heuristics may get screwed e.g. if scroll view shows only 10 items visible and there are 90 items in the source but 50 are in Deleted
state, their data trigger will not take effect unless we scroll to them. So during this the scrollbar will re-calculate and flicker for adjusting its actual scroll value. SO it may luk like we have 100 items applicable for scrolling whereas actually it only needs 50 items to scroll to.
CollectionView provides 50 items to scroll view before hand itself.
So exactaly due to this as far as performance goes, DataTrigger will be faster due to the fact that will apply only apply when the item is de-virtualized i.e. brought in the scroll view. But it may pose the above issues.
Let me know if this helps.
Upvotes: 2
Reputation: 45096
But the Loaded event may have the information you need. From MSDN: The Loaded event is raised before the final rendering, but after the layout system has calculated all necessary values for rendering. Loaded entails that the logical tree that an element is contained within is complete, and connects to a presentation source that provides the HWND and the rendering surface. My interpretation of the is that filters and triggers have been processed but I am not positive. Unloaded is not a final number but I think you would be comparing apples to apples. But still apples may not be the right comparison. It would be so nice if the debugger walked the XAML. Since the debugger does not walk the XAML I just don't think you can directly measure the trigger. The best hope is to measure the page. Create a page with nothing but a difficult filter.
public MainWindow()
{
Debug.WriteLine(DateTime.Now.ToLongTimeString());
InitializeComponent();
Debug.WriteLine(DateTime.Now.ToLongTimeString());
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Debug.WriteLine(DateTime.Now.ToLongTimeString());
Debug is not the same as straight execute so I would bind those 3 times to TextBlocks. And I would also compare with the filter defined in XAML. My gut feel is the are both going to be so fast that it is hard to know the difference but I would guess the filter is faster.
Upvotes: 0