【C#】DataGrid内のTextBlockにスタイルをあてたい
注意:今回の記事の内容では出力にエラーが出てしまいます。
皆さん。DataGrid内の全てのTextBlockのみにスタイルをあてたいってことありますよね。ね、ありますよね。
今回はそう言った皆様の声にお応えすべく、いろいろ試してみました。
そうしたら、ある条件で要求を満たすことができる書き方を見つけました。
まずはDataGridに画像を表示する方法
<DataGridTemplateColumn Header="Img"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Image Source="img/icon.png"/>←ここは{Binding Source}とかにしてもOK </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn>
本題のDataGrid内のTextBlockのみにスタイルをあてる方法
<Window.Resources> <Style TargetType="DataGridCell"> <Setter Property="TextBlock.Foreground" Value="Red" /> <Setter Property="TextBlock.ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content.Text}"/> </Style> </Window.Resources>
なんと、DataGridCellのPropertyにTextBlockを指定することができます。(でも画像とか表示してるとエラーが表示されます)
参考コード
<Window x:Class="TeraDataGridElementStyle.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:TeraDataGridElementStyle" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Window.Resources> <Style TargetType="DataGridCell"> <Setter Property="TextBlock.Foreground" Value="Red" /> <Setter Property="TextBlock.ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content.Text}"/> </Style> </Window.Resources> <Grid> <DataGrid ItemsSource="{Binding DataList}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding No}" Header="No" /> <DataGridTextColumn Binding="{Binding Name}" Header="Name" /> <DataGridTextColumn Binding="{Binding Id}" Header="Id" /> <DataGridTemplateColumn Header="Img"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Image Source="{Binding Source}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </Grid> </Window>
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 TeraDataGridElementStyle { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { ViewModel vm; public MainWindow() { InitializeComponent(); vm = new ViewModel(); for (int i = 0; i < 100; i++) { vm.DataList.Add(new Data { No = i.ToString(), Name = "Name" + i, Id = i.ToString(), Source = "img/icon.png" }); } this.DataContext = vm; } } public class ViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string name) { if (PropertyChanged!=null) PropertyChanged(this, new PropertyChangedEventArgs(name)); } public ObservableCollection<Data> DataList { get; set; } = new ObservableCollection<Data>(); } public class Data { public string No { get; set; } public string Name { get; set; } public string Id { get; set; } public string Source { get; set; } } }
エラー内容
System.Windows.Data Error: 40 : BindingExpression path error: 'Text' property not found on 'object' ''ContentPresenter' (Name='')'. BindingExpression:Path=Content.Text; DataItem='DataGridCell' (Name=''); target element is 'DataGridCell' (Name=''); target property is 'ToolTip' (type 'Object')
結論
エラーが出るプロパティはDataGridTextColumn 等で個別に設定してやろう