Problem with Csla.Wpf.PropertyStatus and "DisconnectedItem"

Problem with Csla.Wpf.PropertyStatus and "DisconnectedItem"

Old forum URL: forums.lhotka.net/forums/t/11010.aspx


stefan posted on Friday, December 23, 2011

Hi,

I am developing a WPF application using VS2010 SP1 and a local version of csla 3.8.4 compiled under .NET4.

In one of my views displaying a list, I just replaced a ListBox using an ItemTemplate with a ListView using a GridView as the View. Both the ListBox and the ListView have VirtualizingStackPanel.IsVirtualizing="True".

I had no Problems with the implementation using a ListBox. I changed to using the ListView just to get sortable columns...

But as soon as I begin to scroll the ListView vertically, I get a NullReferenceException resulting from something called "DisconnectedItem",which seems to be new in WPF under .NET4, and the PropertyStatus control should deal with correctly. At least until they fix an issue in WPF itself...

A quick solution would be to disable virtualization on the ListView. But I want to take advantage of the performance gain I get using it!

Maybe I just need to adjust the PropertyStatus source, but where exactly?

Anybody else already ran into this issue?

Here is the top of the stack strace output (german version):

   bei Csla.Reflection.MethodCaller.GetPropertyValue(Object obj, PropertyInfo info) in C:\Visual Studio Projects\csla38net4\cslacs\Csla\Reflection\MethodCaller.cs:Zeile 682.

   bei Csla.Wpf.PropertyStatus.GetRealSource(Object source, String bindingPath) in C:\Visual Studio Projects\csla38net4\cslacs\Csla\Wpf\PropertyStatus_.cs:Zeile 210.
   bei Csla.Wpf.PropertyStatus.SetSource() in C:\Visual Studio Projects\csla38net4\cslacs\Csla\Wpf\PropertyStatus_.cs:Zeile 171.
   bei Csla.Wpf.PropertyStatus.<.ctor>b__0(Object o, DependencyPropertyChangedEventArgs e) in C:\Visual Studio Projects\csla38net4\cslacs\Csla\Wpf\PropertyStatus_.cs:Zeile 48.
   bei System.Windows.FrameworkElement.RaiseDependencyPropertyChanged(EventPrivateKey key, DependencyPropertyChangedEventArgs args)
   bei System.Windows.FrameworkElement.OnDataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
   bei System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   bei System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   bei System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
   bei System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)

stefan replied on Friday, December 23, 2011

This works:

    <UserControl.Resources>
        <bxfc:VisibilityConverter x:Key="VisibilityConverter" />
        <DataTemplate x:Key="OrderInfo">
                <StackPanel Orientation="Horizontal" DataContext="{Binding Path=Model}">
                    <TextBlock Text="{Binding Path=OrderDate}" Margin="3" Width="60"/>
                    <TextBlock Text="{Binding Path=OrderNumber}" Margin="3" Width="80"
                                Visibility="{Binding ElementName=propStatusOrderNo, Path=CanRead, Converter={StaticResource VisibilityConverter}}" />
                    <cslaxaml:PropertyStatus Name="propStatusOrderNo" Width="0" Height="0" Property="{Binding Path=OrderNumber}" />
                </StackPanel>
        </DataTemplate>
    </UserControl.Resources>
    <Grid DataContext="{Binding Path=OrderList}" Grid.ColumnSpan="1" Grid.Column="1" Grid.RowSpan="1" Grid.Row="2" Name="gridOrderList">
        <ListBox VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling"
                ItemsSource="{Binding}"
                Name="OrderListListBox" 
                ItemTemplate="{StaticResource OrderInfo}"
                ScrollViewer.VerticalScrollBarVisibility="Auto"
                Height="{Binding ElementName=parentGrid, Path=ActualHeight}"
                HorizontalContentAlignment="Stretch">
        </ListBox>
    </Grid>

This does not:

    <ListView VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling"
            ItemsSource="{Binding}"
            Name="OrderListListView"
            Height="{Binding ElementName=parentGrid, Path=ActualHeight}"
            HorizontalContentAlignment="Stretch"
            IsSynchronizedWithCurrentItem="True"
            attprops:GridViewSort.AutoSort="True">
        <ListView.View>
            <GridView>
                <GridView.Columns>
                    <GridViewColumn Header="OrderDate" DisplayMemberBinding="{Binding Path=Model.OrderDate}" Width="60" attprops:GridViewSort.PropertyName="Model.OrderDate"/>
                    <GridViewColumn Header="OrderNumber" attprops:GridViewSort.PropertyName="Model.OrderNumber">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="{Binding Path=Model.OrderNumber}" Margin="3" Width="80"
                                                Visibility="{Binding ElementName=propStatusOrderNo, Path=CanRead, Converter={StaticResource VisibilityConverter}}" />
                                    <cslaxaml:PropertyStatus Name="propStatusOrderNo" Width="0" Height="0" Property="{Binding Path=Model.OrderNumber}" />
                                </StackPanel>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView.Columns>
            </GridView>
        </ListView.View>
    </ListView>

stefan replied on Friday, December 23, 2011

Found the solution myself... it has nothing to do with the "DisconnectedItem" thing nor the PropertyStatus control!

It is a matter of providing a common DataContext for related controls the right way...

I just had to set the DataContext on the container element:

                    <GridViewColumn Header="OrderNumber" attprops:GridViewSort.PropertyName="Model.OrderNumber">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal" DataContext="{Binding Path=Model}">
                                    <TextBlock Text="{Binding Path=OrderNumber}" Margin="3" Width="80"
                                                Visibility="{Binding ElementName=propStatusOrderNo, Path=CanRead, Converter={StaticResource VisibilityConverter}}" />
                                    <cslaxaml:PropertyStatus Name="propStatusOrderNo" Width="0" Height="0" Property="{Binding Path=OrderNumber}" />
                                </StackPanel>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

Copyright (c) Marimer LLC