<ContentControl Grid.Column="0"
Template="{StaticResource DataGridControlTemplate}"
ToolTip="Template"/>
<ContentControl Grid.Column="1"
ContentTemplate="{StaticResource SelectedDataTemplate}"
Content="{Binding SelectedBook}"
ToolTip="ContentTemplate"/>
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<Binding Source="{StaticResource DataGridDataTemplate}"/>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<Window x:Class="WpfApp16.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp16"
mc:Ignorable="d"
Title="ContentControl And Template,ControlTemplate" WindowState="Maximized">
<Window.DataContext>
<local:MainVM/>
</Window.DataContext>
<Window.Resources>
<Style TargetType="DataGridRow">
<Setter Property="FontSize" Value="30"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
<DataTemplate DataType="{x:Type local:Book}"
x:Key="DataGridDataTemplate">
<DataTemplate.Resources>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="10,0"/>
<Setter Property="FontSize" Value="20"/>
</Style>
</DataTemplate.Resources>
<Border BorderBrush="LightBlue"
BorderThickness="2"
Margin="5,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" >Id:<Run Text="{Binding Id}"></Run></TextBlock>
<TextBlock Grid.Row="0" Grid.Column="1">Name:<Run Text="{Binding Name}"></Run></TextBlock>
<TextBlock Grid.Row="0" Grid.Column="2">ISBN:<Run Text="{Binding ISBN}"></Run></TextBlock>
<TextBlock Grid.Row="0" Grid.Column="3">Comment:<Run Text="{Binding Comment}"></Run></TextBlock>
<TextBlock Grid.Row="1" Grid.Column="0">Content:<Run Text="{Binding Content}"></Run></TextBlock>
<TextBlock Grid.Row="1" Grid.Column="1">Summary:<Run Text="{Binding Summary}"></Run></TextBlock>
<TextBlock Grid.Row="1" Grid.Column="2">Title:<Run Text="{Binding Title}"></Run></TextBlock>
<TextBlock Grid.Row="1" Grid.Column="3">Topic:<Run Text="{Binding Topic}"></Run></TextBlock>
</Grid>
</Border>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Book}"
x:Key="SelectedDataTemplate">
<GroupBox Header="Selected Item"
BorderBrush="DarkBlue"
BorderThickness="5"
Margin="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition Height="2*"/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="50"/>
<Setter Property="TextWrapping" Value="Wrap"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<TextBlock Grid.Row="0" >Id:<Run Text="{Binding Id}"></Run></TextBlock>
<TextBlock Grid.Row="1" >Name:<Run Text="{Binding Name}"></Run></TextBlock>
<TextBlock Grid.Row="2" >ISBN:<Run Text="{Binding ISBN}"></Run></TextBlock>
<TextBlock Grid.Row="3" >Comment:<Run Text="{Binding Comment}"></Run></TextBlock>
<TextBlock Grid.Row="4" >Content:<Run Text="{Binding Content}"></Run></TextBlock>
<TextBlock Grid.Row="5" >Summary:<Run Text="{Binding Summary}"></Run></TextBlock>
<TextBlock Grid.Row="6" >Title:<Run Text="{Binding Title}"></Run></TextBlock>
<TextBlock Grid.Row="7" >Topic:<Run Text="{Binding Topic}"></Run></TextBlock>
</Grid>
</GroupBox>
</DataTemplate>
<ControlTemplate TargetType="ContentControl" x:Key="DataGridControlTemplate">
<GroupBox Header="All Item"
Margin="5">
<DataGrid ItemsSource="{Binding Books}"
SelectedItem="{Binding SelectedBook}"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
VirtualizingPanel.CacheLength="5,5"
SnapsToDevicePixels="True"
UseLayoutRounding="True"
ScrollViewer.CanContentScroll="True"
ScrollViewer.IsDeferredScrollingEnabled="False"
AutoGenerateColumns="False"
CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<Binding Source="{StaticResource DataGridDataTemplate}"/>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</GroupBox>
</ControlTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ContentControl Grid.Column="0"
Template="{StaticResource DataGridControlTemplate}"
ToolTip="Template"/>
<ContentControl Grid.Column="1"
ContentTemplate="{StaticResource SelectedDataTemplate}"
Content="{Binding SelectedBook}"
ToolTip="ContentTemplate"/>
</Grid>
</Window>
using Microsoft.Xaml.Behaviors;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml.Serialization;
namespace WpfApp16
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
public class MainVM : INotifyPropertyChanged
{
private static long id = 1;
private static (long, long) GetStartEnd(long interval)
{
long end = Interlocked.Add(ref id, interval);
long start = end - interval;
return (start, end);
}
public MainVM()
{
if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
{
return;
}
Books = new ObservableCollection<Book>();
_ = InitBooksAsync();
}
private async Task InitBooksAsync(long cnt = 1000000)
{
var (start, end) = GetStartEnd(cnt);
Books.Clear();
await Task.Run(async() =>
{
List<Book> bks = new List<Book>();
for (long i = start; i < end; i++)
{
bks.Add(new Book()
{
Id = i,
Name = $"Name_{i}",
ISBN = $"ISBN_{i}_{Guid.NewGuid():N}",
Comment = $"Comment_{i}",
Content = $"Content_{i}",
Summary = $"Summary_{i}",
Title = $"Title_{i}",
Topic = $"Topic_{i}"
});
}
Application.Current?.Dispatcher.InvokeAsync(() =>
{
Books = new ObservableCollection<Book>(bks);
});
await Task.Delay(0);
});
}
private Book selectedBook;
public Book SelectedBook
{
get
{
return selectedBook;
}
set
{
if(value!=selectedBook)
{
selectedBook = value;
OnPropertyChanged();
}
}
}
private ObservableCollection<Book> books;
public ObservableCollection<Book> Books
{
get
{
return books;
}
set
{
if (value != books)
{
books = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler? PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propName = "")
{
var handler = Volatile.Read(ref PropertyChanged);
if (handler != null)
{
handler?.Invoke(this, new PropertyChangedEventArgs(propName));
}
}
}
public class Book
{
public long Id { get; set; }
public string Name { get; set; }
public string ISBN { get; set; }
public string Comment { get; set; }
public string Content { get; set; }
public string Summary { get; set; }
public string Title { get; set; }
public string Topic { get; set; }
}
}
![image]()
![image]()