WPF DatagridRow set width and background in mvvm,DataGridTextColumn wrap

 

 

<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();
        }
    }
}

 

posted @ 2025-06-12 23:36  FredGrit  阅读(13)  评论(0)    收藏  举报