WPF ContentControl Template is ControlTemplate, ContentTemplate is DataTemplate and must assign value to Content explicitly

 <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

 

posted @ 2026-07-17 21:37  FredGrit  阅读(6)  评论(0)    收藏  举报