質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

解決済

WPF DataGridのCellStyleについて

Coriander
Coriander

総合スコア12

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

2回答

0グッド

1クリップ

7943閲覧

投稿2020/02/14 04:27

編集2020/02/14 05:37

初歩的な質問になりますが、DataGridTextColumnのCellStyleに対してViewModelのプロパティでDataTriggerを仕掛けても期待通りの動作となりませんでした。
詳細としては、以下の通りシンプルなViewにbool型のIsEditプロパティを指定し、ViewModel側でTrue/Falseを切り替えてもBorderBrushに変化がありませんでした。IsEditをDataGrid以外のほかの要素に同様にStyle Triggerを指定すると正しく動作するのでbindは問題なさそうです。

一方、ItemSourceとしてバインドしているItemsコレクションのAgeプロパティをDataTriggerとしてBindingに指定しValueへ任意の数値を指定し、DataGrid上でその数値を入力するとStyleは正しく適用されます。

bool型プロパティで指定した場合、なぜTriggerは動作しないのでしょうか?

View

<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Header="名前" Width="150" Binding="{Binding Name}"/> <DataGridTextColumn Header="年齢" Width="100" Binding="{Binding Age}"> <DataGridTextColumn.CellStyle> <Style TargetType="{x:Type DataGridCell}"> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="Background" Value="#87CEEB"/> <Setter Property="Foreground" Value="Black"/> </Trigger> <DataTrigger Binding="{Binding IsEdit}" Value="True"> <Setter Property="BorderBrush" Value="Red"/> </DataTrigger> </Style.Triggers> </Style> </DataGridTextColumn.CellStyle> </DataGridTextColumn> </DataGrid.Columns> </DataGrid>

ViewModel

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using Livet; using Livet.Commands; using Livet.Messaging; using Livet.Messaging.IO; using Livet.EventListeners; using Livet.Messaging.Windows; using System.Collections.ObjectModel; namespace InspectDataGrid.ViewModels { public class MainWindowViewModel : ViewModel { private ObservableCollection<Item> items; public ObservableCollection<Item> Items { get { return items; } set { items = value; RaisePropertyChanged(); } } private bool isEdit; public bool IsEdit { get { return isEdit; } set { isEdit = value; RaisePropertyChanged(); } } private ViewModelCommand settruecommand; public ViewModelCommand SetTrueCommand { get { if (settruecommand ==null) { settruecommand = new ViewModelCommand(this.SetTrue); } return settruecommand; } } private ViewModelCommand setfalsecommand; public ViewModelCommand SetFalseCommand { get { if (setfalsecommand ==null) { setfalsecommand = new ViewModelCommand(this.SetFalse); } return setfalsecommand; } } public MainWindowViewModel() { this.Items = new ObservableCollection<Item>(); this.Items.Add(new Item("a", 24)); this.Items.Add(new Item("b", 25)); } public void Initialize() { } public void SetTrue() { this.IsEdit = true; } public void SetFalse() { this.IsEdit = false; } }

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

Zuishin

2020/02/14 04:39

とりあえず前の質問を片付けましょう。解決したならベストアンサーを選び、そうでないなら何が問題なのかを質問を編集して追記してください。
Coriander

2020/02/14 04:44

すみません、質問を投げてそのまま放置してしまっていたので解決済みとしました。以後気を付けます。
hihijiji

2020/02/14 04:52

パッと見では動きそうですが、動かないならViewModel側かBindingの仕方が間違っているのでは? View以外のコードもUPしてください。
Coriander

2020/02/14 05:38

>hijiji様 ViewModel側のコードを追加しました。ご確認お願いします。

回答2

2

ベストアンサー

Binding="{Binding Name}"で楽にバインディングできるのは、そのDataContextが個々のItemになっているためです。

MainWindowViewModelのものにバインディングしたい場合、RelativeSource等で探してくる必要があります(あまりに頻発するようですと、クラス設計が間違えている可能性があります)

xaml

1<Window 2 x:Class="Questions241295.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Questions241295" 6 Title="MainWindow" 7 Width="800" 8 Height="450"> 9 <Window.DataContext> 10 <local:MainWindowViewModel /> 11 </Window.DataContext> 12 <Grid> 13 <Grid.RowDefinitions> 14 <RowDefinition Height="Auto" /> 15 <RowDefinition /> 16 </Grid.RowDefinitions> 17 <StackPanel Orientation="Horizontal"> 18 <Button Command="{Binding SetTrueCommand}" Content="IsEditMain True" /> 19 <Button Command="{Binding SetFalseCommand}" Content="IsEditMain False" /> 20 <Button Command="{Binding SelectedItem.SetTrueCommand, ElementName=dataGrid}" Content="Selected IsEditItem True" /> 21 <Button Command="{Binding SelectedItem.SetFalseCommand, ElementName=dataGrid}" Content="Selected IsEditItem False" /> 22 23 <TextBlock Text="{Binding IsEditMain, StringFormat=IsEditMain {0}}" /> 24 </StackPanel> 25 <DataGrid 26 x:Name="dataGrid" 27 Grid.Row="1" 28 AutoGenerateColumns="False" 29 ItemsSource="{Binding Items}"> 30 <DataGrid.Columns> 31 <DataGridTextColumn Binding="{Binding Name}" Header="名前" /> 32 <DataGridTextColumn Binding="{Binding Age}" Header="年齢"> 33 <DataGridTextColumn.CellStyle> 34 <Style TargetType="{x:Type DataGridCell}"> 35 <Style.Triggers> 36 <Trigger Property="IsSelected" Value="True"> 37 <Setter Property="Background" Value="#87CEEB" /> 38 <Setter Property="Foreground" Value="Black" /> 39 </Trigger> 40 <DataTrigger Binding="{Binding IsEditItem}" Value="True"> 41 <Setter Property="BorderBrush" Value="Red" /> 42 </DataTrigger> 43 <DataTrigger Binding="{Binding DataContext.IsEditMain, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Value="True"> 44 <Setter Property="Foreground" Value="Red" /> 45 </DataTrigger> 46 </Style.Triggers> 47 </Style> 48 </DataGridTextColumn.CellStyle> 49 </DataGridTextColumn> 50 <DataGridTextColumn 51 Binding="{Binding IsEditItem}" 52 Header="IsEditItem" 53 IsReadOnly="True" /> 54 </DataGrid.Columns> 55 </DataGrid> 56 </Grid> 57</Window>

C#

1using System.Collections.ObjectModel; 2using System.Windows; 3using Livet; 4using Livet.Commands; 5 6namespace Questions241295 7{ 8 public partial class MainWindow : Window 9 { 10 public MainWindow() => InitializeComponent(); 11 } 12 13 public class MainWindowViewModel : ViewModel 14 { 15 public ObservableCollection<Item> Items { get; } 16 17 private bool isEdit; 18 public bool IsEditMain { get => isEdit; set => RaisePropertyChangedIfSet(ref isEdit, value); } 19 20 private ViewModelCommand setTrueCommand; 21 public ViewModelCommand SetTrueCommand => setTrueCommand ?? (setTrueCommand = new ViewModelCommand(SetTrue)); 22 23 private ViewModelCommand setFalseCommand; 24 public ViewModelCommand SetFalseCommand => setFalseCommand ?? (setFalseCommand = new ViewModelCommand(SetFalse)); 25 26 public MainWindowViewModel() 27 { 28 Items = new ObservableCollection<Item> 29 { 30 new Item("a", 24), 31 new Item("b", 25) 32 }; 33 } 34 35 public void SetTrue() => IsEditMain = true; 36 public void SetFalse() => IsEditMain = false; 37 } 38 39 public class Item : ViewModel 40 { 41 private string name; 42 public string Name { get => name; set => RaisePropertyChangedIfSet(ref name, value); } 43 44 private int age; 45 public int Age { get => age; set => RaisePropertyChangedIfSet(ref age, value); } 46 47 private bool isEdit; 48 public bool IsEditItem { get => isEdit; set => RaisePropertyChangedIfSet(ref isEdit, value); } 49 50 private ViewModelCommand setTrueCommand; 51 public ViewModelCommand SetTrueCommand => setTrueCommand ?? (setTrueCommand = new ViewModelCommand(SetTrue)); 52 53 private ViewModelCommand setFalseCommand; 54 public ViewModelCommand SetFalseCommand => setFalseCommand ?? (setFalseCommand = new ViewModelCommand(SetFalse)); 55 56 public Item(string name, int age) => (Name, Age) = (name, age); 57 58 public void SetTrue() => IsEditItem = true; 59 public void SetFalse() => IsEditItem = false; 60 } 61}
  • IsEditItem 個々のIsEdit(ボーダー赤)
  • IsEditMain 全体のIsEdit(文字赤)

投稿2020/02/14 11:56

TN8001

総合スコア8046

Zuishin, Coriander👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

Coriander

2020/02/15 00:42

ご回答ありがとうございます。DataContextとItemSourceの関係をしっかり理解していなかったことが原因でした。RelativeSourceについてもう少し勉強してみます。

2

AgeとIsEditを同様に扱いたいならIsEditはItemクラスに入れるのが筋だと思います。
Ageもそこにあるでしょ?

投稿2020/02/14 06:13

hihijiji

総合スコア4150

Zuishin, Coriander👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

Coriander

2020/02/15 00:44

ご回答ありがとうございます。勉強不足でなぜItemクラスに入れるべきなのか理解できませんでしたが、納得できました。

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです