LoginSignup
0
1

More than 5 years have passed since last update.

Visual Studio / WPF > DataGrid > 2列だけ色を変える > IValueConverterの使用 > 一部失敗

Last updated at Posted at 2017-06-11
動作環境
Windows 7 Pro (32bit)
Microsoft Visual Studio 2017 Community

http://qiita.com/7of9/items/f9583159827d5f80a897
の続き。

DataGridのIsReadOnly=trueとした上で、2列だけ色を変更したくなった。

test.csv

アプリケーション実行ファイル生成フォルダに以下のファイルを用意する。

test.csv
Name1,Race1,Codename1
7of9,Borg,seven
Janeway,Human,Captain
Odo,Unknown,Odo

全 C# script

MainWindow.xaml.cs
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;
//
using System.IO;
using System.Globalization;
using System.Data;

namespace _170611_t1030_readCsvFile
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void B_read_Click(object sender, RoutedEventArgs e)
        {
            string appPath = System.AppDomain.CurrentDomain.BaseDirectory;
            string filename = "test.csv";
            string filepath = appPath + "\\" + filename;
            if (File.Exists(filepath) == false) {
                return;
            }
            this.DataContext = PersonService.ReadFile(filepath);
            PersonService.SetHeaders(filepath, dg1);
        }
    }

    // Name, Race, Codename
    public class Person
    {
        public string Name { get; set; }
        public string Race { get; set; }
        public string Codename { get; set; }
    }
    public static class PersonService
    {
        public static List<Person> ReadFile(string filepath)
        {
            var lines = File.ReadAllLines(filepath);

            var data = from l in lines.Skip(1)
                       let split = l.Split(',')
                       select new Person
                       {
                           Name = split[0],
                           Race = split[1],
                           Codename = split[2]
                       };
            return data.ToList();
        }
        public static void SetHeaders(string filepath, DataGrid dataGrid)
        {
            var lines = File.ReadAllLines(filepath);

            int idx = 0;
            foreach(var aline in lines[0].Split(','))
            {
                dataGrid.Columns[idx].Header = aline;
                idx++;
            }
        }
    }

    public class ValueToBrushConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string input;
            int idx;
            try
            {
                DataGridCell dgc = (DataGridCell)value;
                idx = dgc.Column.DisplayIndex;
            }
            catch (InvalidCastException e)
            {
                return DependencyProperty.UnsetValue;
            }
            if (idx < 2)
            {
                return Brushes.LightGreen;
            }
            return DependencyProperty.UnsetValue;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

C# script 主な部分

参考: https://stackoverflow.com/questions/5549617/change-datagrid-cell-colour-based-on-values
の以下の回答を参考にした。
answered Jul 12 '13 at 17:10
unwrittenrainbow

セルの値でなく、列のため.Column.DisplayIndexを使用。

MainWindow.xaml.cs
//snippet
    public class ValueToBrushConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string input;
            int idx;
            try
            {
                DataGridCell dgc = (DataGridCell)value;
                idx = dgc.Column.DisplayIndex;
            }
            catch (InvalidCastException e)
            {
                return DependencyProperty.UnsetValue;
            }
            if (idx < 2)
            {
                return Brushes.LightGreen;
            }
            return DependencyProperty.UnsetValue;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

XAMLファイル

MainWindow.xaml
<Window x:Class="_170611_t1030_readCsvFile.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:_170611_t1030_readCsvFile"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:ValueToBrushConverter x:Key="ValueToBrushConverter"/>
        <Style x:Key="CellStyle" TargetType="DataGridCell">
            <Setter Property="Background" 
                    Value="{Binding RelativeSource={RelativeSource Self}, 
                    Converter={StaticResource ValueToBrushConverter}}"/>
        </Style>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <Button x:Name="B_read" Content="Read"
                    Click="B_read_Click" Height="28" Width="100"/>
            <DataGrid Height="300" x:Name="dg1"
                      AutoGenerateColumns="True"
                      IsReadOnly="true"
                      CellStyle="{StaticResource CellStyle}"
                      ItemsSource="{Binding}">
            </DataGrid>
        </StackPanel>
    </Grid>
</Window>

2017-06-11_13h36_49.png

もっと簡単な方法があるように思う。

不具合

クリックした時に文字が読めなくなるという不具合がある。
このあたりの扱いは今後。

2017-06-11_13h42_53.png

色をつけない(CellStyle="{StaticResource CellStyle}"を指定しない)場合は以下のようになる。
2017-06-11_13h45_11.png

関連リンク

コンバータによるデータ変換
http://www.atmarkit.co.jp/ait/articles/0905/19/news145_4.html

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1