<Setter Property="Width" Value="{Binding DataContext.RowWidth,
RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}},
Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<Setter Property="Background" Value="{Binding ImgUrl, Converter={StaticResource ImageToBrush}}"/>
<DataGridTextColumn Binding="{Binding ISBN}" Header="ISBN" Width="*">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
![]()
//all
//xaml
<Window x:Class="WpfApp1.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:WpfApp1"
mc:Ignorable="d"
WindowState="Maximized"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:ImageSourceToBrushConverter x:Key="ImageToBrush"/>
</Window.Resources>
<Grid x:Name="gd">
<DataGrid x:Name="dg"
ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
SelectedIndex="{Binding SelectedIdx,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
SelectionMode="Extended"
AutoGenerateColumns="False"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.CacheLengthUnit="Item"
VirtualizingPanel.CacheLength="1"
VirtualizingPanel.VirtualizationMode="Recycling">
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Height" Value="300"/>
<Setter Property="FontSize" Value="50"/>
<!--<Setter Property="Width" Value="{Binding DataContext.RowWidth,
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>-->
<!--<Setter Property="local:DataGridRowHelper.RowWidth"
Value="{Binding DataContext.RowWidth,
RelativeSource={RelativeSource AncestorType=DataGrid}}" />-->
<Setter Property="Width" Value="{Binding DataContext.RowWidth,
RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}},
Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<Setter Property="Background" Value="{Binding ImgUrl, Converter={StaticResource ImageToBrush}}"/>
<Setter Property="Foreground" Value="Black"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Height" Value="500"/>
<Setter Property="FontSize" Value="80"/>
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Id}" Header="Id" Width="*"/>
<DataGridTextColumn Binding="{Binding Name}" Header="Name" Width="*"/>
<DataGridTextColumn Binding="{Binding ISBN}" Header="ISBN" Width="*">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Title}" Header="Title" Width="*"/>
<!--<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.Background>
<ImageBrush ImageSource="{Binding DataContext.ImgSource,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type DataGridRow}}}" Stretch="Uniform"/>
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Id}" Grid.Column="0"/>
<TextBlock Text="{Binding Name}" Grid.Column="1"/>
<TextBlock Text="{Binding ISBN}" Grid.Column="2" TextWrapping="Wrap"/>
<TextBlock Text="{Binding Title}" Grid.Column="3"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>-->
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
//cs
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.IO;
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;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var vm = new MainVM(this);
this.DataContext = vm;
}
}
public class MainVM : INotifyPropertyChanged
{
private Window win;
private FrameworkElement fe;
public MainVM(Window winValue)
{
win = winValue;
if(win != null)
{
win.Loaded += Win_Loaded;
}
}
private void Win_Loaded(object sender, RoutedEventArgs e)
{
InitBooksCollection();
var tempFe=win.Content as FrameworkElement;
if(tempFe != null)
{
fe=tempFe;
RowWidth= fe.ActualWidth-50;
}
}
private void InitBooksCollection()
{
BooksCollection = new ObservableCollection<Book>();
string imgDir = @"../../../Images";
if(Directory.Exists(imgDir))
{
var imgs = Directory.GetFiles(imgDir);
int imgsCount = imgs.Count();
for(int i=0;i<100000;i++)
{
BooksCollection.Add(new Book()
{
Id=i+1,
Name=$"Name_{i+1}",
Title=$"Title_{i+1}",
ISBN=$"ISBN_{Guid.NewGuid().ToString("N")}",
ImgUrl= imgs[i % imgsCount],
ImgSource = GetImgSourceViaUrl(imgs[i%imgsCount])
});
}
}
}
private ImageSource GetImgSourceViaUrl(string imgUrl)
{
BitmapImage bmi = new BitmapImage();
bmi.BeginInit();
bmi.UriSource = new Uri(imgUrl, UriKind.RelativeOrAbsolute);
bmi.EndInit();
if(bmi.CanFreeze)
{
bmi.Freeze();
}
return bmi;
}
public event PropertyChangedEventHandler? PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
private double rowWidth;
public double RowWidth
{
get
{
return rowWidth;
}
set
{
if(value!=rowWidth)
{
rowWidth = value;
OnPropertyChanged(nameof(RowWidth));
}
}
}
private int selectedIdx;
public int SelectedIdx
{
get
{
return selectedIdx;
}
set
{
if(value!=selectedIdx)
{
selectedIdx = value;
OnPropertyChanged(nameof(SelectedIdx));
}
}
}
private ObservableCollection<Book> booksCollection;
public ObservableCollection<Book> BooksCollection
{
get
{
return booksCollection;
}
set
{
if (value != booksCollection)
{
booksCollection = value;
OnPropertyChanged(nameof(BooksCollection));
}
}
}
}
public static class DataGridRowHelper
{
public static readonly DependencyProperty RowWidthProperty =
DependencyProperty.RegisterAttached(
"RowWidth",
typeof(double),
typeof(DataGridRowHelper),
new PropertyMetadata(double.NaN, OnRowWidthChanged));
public static void SetRowWidth(DependencyObject element, double value)
{
element.SetValue(RowWidthProperty, value);
}
public static double GetRowWidth(DependencyObject element)
{
return (double)element.GetValue(RowWidthProperty);
}
private static void OnRowWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is DataGridRow row)
{
row.Width = (double)e.NewValue;
}
}
}
public class Book
{
public int Id { get; set; }
public string Name { get; set; }
public string ISBN { get; set; }
public string ImgUrl { get; set; }
public string Title { get; set; }
public ImageSource ImgSource { get; set; }
}
public class ImageSourceToBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is string imagePath)
{
return new ImageBrush(new BitmapImage(new Uri(imagePath,UriKind.RelativeOrAbsolute)));
}
return Brushes.Transparent;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}