ControlTemplate для DataGridCell
Я работаю над решением для виртуализации данных, которое Бе Столльниц представила в своем блоге. Это решение предназначено для работы с ListView
, Я просто пытаюсь заставить его работать с WPF DataGrid
но я не преуспел в моей попытке.
Вот код для полного рабочего примера, предоставленного ей.
ListView
в предоставленном коде привязан к обычаю AsyncVirtualizingCollection
коллекция class
, Но когда я пытаюсь связать эту коллекцию с DataGrid, она отображает пустые строки. Данные не отображаются в DataGrid
,
Теперь магия происходит так, как ControlTemplate
написано для ListViewItem
, Я обнулил его до ContentPresenter
в ControlTemplate
, ContentPresenter
был заменен на Border
ведя себя как ContentPresenter
, Ниже приводится XAML для того же:
<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>
Теперь, внимательно изучив GridViewRowPresenter
в Grid
внутри второй границы вы можете заметить: Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content.Data}"
Я думаю, что это линия, которая помогает в отображении данных.
Я пытался создать ControlTemplate
для DataGridCell
следующим образом:
<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>
но я до сих пор не получаю никаких данных в DataGrid
,
Я не уверен, что мне здесь не хватает, так как я не очень хорошо разбираюсь в шаблонах и стилях.
Я старался держать это как можно точнее, чтобы не делать это слишком скучным. Если вы думаете, что я пропустил любую информацию, пожалуйста, спросите, я был бы более чем рад предоставить это.
Любая помощь будет принята с благодарностью.
Примечание. Связанное приложение предназначено для.Net 3.5 и должно быть преобразовано для.Net 4.0, чтобы иметь возможность использовать DataGrid.
1 ответ
Поскольку DataWrapper
это предмет для вашего DataGrid
который упаковывает фактический элемент в Data
Свойство, вы должны обновить привязку столбца, как:
<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>
Точно так же вам нужно установить привязку в вашем ControlTemplate как:
<ContentPresenter Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />