Question

I am working on a Data Virtualization solution provided by Bea Stollnitz on her blog. This solution is provided to work with a ListView. I am just trying to make it work with WPF DataGrid but I am not successful in my attempt.

Here is the code for the full working example provided by her.

The ListView in the provided code is bound to an custom AsyncVirtualizingCollection collection class. But when I try to bind this collection to the DataGrid, it does display blank rows. The data does not appear in the DataGrid.

Now the magic happens in the way the ControlTemplate is written for the ListViewItem. I have zeroed it down to the ContentPresenter in the ControlTemplate. The ContentPresenter has been replaced with a Border behaving as the ContentPresenter. Following is XAML for the same:

<Style TargetType="{x:Type ListViewItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListViewItem}">
                <Border BorderThickness="{TemplateBinding BorderThickness}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        Background="{TemplateBinding Background}"
                        CornerRadius="2"
                        SnapsToDevicePixels="true">
                    <Border Name="InnerBorder" CornerRadius="1" BorderThickness="1">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition MaxHeight="11"/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                            <Rectangle Name="UpperHighlight" Visibility="Collapsed" Fill="#75FFFFFF"/>
                            <GridViewRowPresenter Grid.RowSpan="2"
                                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                                    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                                    Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content.Data}"/>
                            <StackPanel Name="Loading" Orientation="Horizontal" Grid.RowSpan="2" Visibility="Collapsed">
                                <TextBlock Text="Loading item " />
                                <TextBlock Text="{Binding ItemNumber}" />
                                <TextBlock Text="..." />
                            </StackPanel>
                        </Grid>
                    </Border>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Now, on having a close look at the GridViewRowPresenter in the Grid inside the second border, you might notice: Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content.Data}"

I think this is the line that helps in displaying data.

I tried creating a ControlTemplate for the DataGridCell as following:

<Style TargetType="{x:Type DataGridCell}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="DataGridCell" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
                <Border BorderThickness="{TemplateBinding Border.BorderThickness}" 
                    BorderBrush="{TemplateBinding Border.BorderBrush}" 
                    Background="{TemplateBinding Panel.Background}" 
                    SnapsToDevicePixels="True">
                    <ContentPresenter Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content.Data}" 
                        ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
                        ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" 
                        SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

but I still do not get any data in the DataGrid.

I am not sure what I am missing here as I am not good with templates and styles.

I tried to keep this as precise as possible in order to avoid making it too boring. I you think I have missed out any information please do ask, I would be more than happy to provide that.

Any help would be greatly appreciated.

Note: The linked application targets .Net 3.5 and would need to converted for .Net 4.0 to be able to use DataGrid.

Was it helpful?

Solution

Since DataWrapper is the item for your DataGrid which is wraping the actual item in Data Property, you should update your column binding like:

<DataGrid Grid.Row="2" ItemsSource="{Binding}" AutoGenerateColumns="False" 
                       IsSynchronizedWithCurrentItem="True" Name="dg"  
                       HorizontalAlignment="Center" Margin="5" Height="300" Width="400"> 
     <DataGrid.Columns> 
           <DataGridTextColumn Header="Id" Binding="{Binding Data.Id}" Width="100"/>  
           <DataGridTextColumn Header="Name" Binding="{Binding Data.Name}" Width="100"/>  
     </DataGrid.Columns> 
</DataGrid>

Similarly you will have to set the binding in your ControlTemplate like:

<ContentPresenter Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top