WPF Datagrid DataGridTemplateColumn.CellTemplate local:ImageTextblock ImgUrl="{Binding DataContext.ImageUrl,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow}}}

DataGridTemplate.CellTemplate contains one datatemplae will display the customoized control,the key located at the custom control's dependency property binding and relative source of x:type datagridrow

<local:ImageTextblock ImgUrl="{Binding DataContext.ImageUrl,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow}}}" Width="200" Height="500"
                      TbkStr="{Binding DataContext.Name,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow}}}"/>

 

 

 

 

//customize user control
<UserControl x:Class="WpfApp364.ImageTextblock"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApp364"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Image Source="{Binding ImgUrl}" Width="200" Height="500" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
        <TextBlock Text="{Binding TbkStr}"
                   HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="30" />
    </Grid>
</UserControl>


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 WpfApp364
{
    /// <summary>
    /// Interaction logic for ImageTextblock.xaml
    /// </summary>
    public partial class ImageTextblock : UserControl
    {
        public ImageTextblock()
        {
            InitializeComponent();
            this.DataContext = this;
        }


        public string ImgUrl
        {
            get { return (string)GetValue(ImgUrlProperty); }
            set { SetValue(ImgUrlProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ImgUrl.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ImgUrlProperty =
            DependencyProperty.Register("ImgUrl", typeof(string), 
                typeof(ImageTextblock), new PropertyMetadata(null));




        public string TbkStr
        {
            get { return (string)GetValue(TbkStrProperty); }
            set { SetValue(TbkStrProperty, value); }
        }

        // Using a DependencyProperty as the backing store for TbkStr.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TbkStrProperty =
            DependencyProperty.Register("TbkStr", typeof(string), 
                typeof(ImageTextblock), new PropertyMetadata(null));




    }
}

 

 

 

<Window x:Class="WpfApp364.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:WpfApp364"
        mc:Ignorable="d" 
        WindowState="Maximized"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:BookVM/>
    </Window.DataContext>
    <Grid>
        <DataGrid ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                  CanUserAddRows="False" AutoGenerateColumns="False"
                  VirtualizingPanel.VirtualizationMode="Recycling"
                  VirtualizingPanel.IsVirtualizing="True"
                  VirtualizingPanel.IsContainerVirtualizable="True">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Id" Binding="{Binding Id}"/>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                <DataGridTemplateColumn Header="Image">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <local:ImageTextblock ImgUrl="{Binding DataContext.ImageUrl,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow}}}" Width="200" Height="500"
                                                  TbkStr="{Binding DataContext.Name,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow}}}"/>
                            <!--<Grid>
                                <Image Source="{Binding ImageUrl,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="200" Height="500"/>
                                <TextBlock Text="{Binding Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
            HorizontalAlignment="Stretch" VerticalAlignment="Center" />
                            </Grid>-->
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
            
        </DataGrid>
    </Grid>
</Window>






//cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 WpfApp364
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class BookVM : INotifyPropertyChanged
    {
        public BookVM()
        {
            InitData();
        }

        private void InitData()
        {
            BooksCollection = new ObservableCollection<Book>();
            var imgsList = System.IO.Directory.GetFiles(@"../../Images");
            int imgsCnt = imgsList.Count();
            for (int i = 0; i < 100000; i++)
            {
                BooksCollection.Add(new Book()
                {
                    Id = i + 1,
                    Name = $"Name_{i + 1}",
                    ImageUrl = imgsList[i % imgsCnt]
                });
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler?.Invoke(this, new PropertyChangedEventArgs(propName));
            }
        }

        private ObservableCollection<Book> booksCollection;
        public ObservableCollection<Book> BooksCollection
        {
            get
            {
                return booksCollection;
            }
            set
            {
                if (value != booksCollection)
                {
                    booksCollection = value;
                    OnPropertyChanged(nameof(BooksCollection));
                }
            }
        }
    }

    public class DelCmd : ICommand
    {
        public event EventHandler CanExecuteChanged
        {
            add
            {
                CommandManager.RequerySuggested += value;
            }
            remove
            {
                CommandManager.RequerySuggested -= value;
            }
        }

        private Action<object> execute;
        private Predicate<object> canExecute;

        public DelCmd(Action<object> executeValue, Predicate<object> canExecuteValue)
        {
            execute = executeValue;
            canExecute = canExecuteValue;
        }

        public bool CanExecute(object parameter)
        {
            if (canExecute == null)
            {
                return true;
            }
            return canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            execute(parameter);
        }
    }

    public class Book
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string ImageUrl { get; set; }
    }
}

 

posted @ 2024-09-13 23:52  FredGrit  阅读(5)  评论(0编辑  收藏  举报