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

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

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

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

XAML

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

WPF

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

Q&A

解決済

2回答

11833閲覧

WPF DataGridのCellStyleについて

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 クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

1グッド

0クリップ

投稿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; } }
TN8001👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

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側のコードを追加しました。ご確認お願いします。
guest

回答2

0

ベストアンサー

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

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

xml

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 Width="800" 7 Height="450"> 8 <Window.DataContext> 9 <local:MainWindowViewModel /> 10 </Window.DataContext> 11 <DockPanel> 12 <StackPanel DockPanel.Dock="Top"> 13 <CheckBox VerticalContentAlignment="Center" Content="IsEditMain" IsChecked="{Binding IsEditMain}" /> 14 </StackPanel> 15 <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Items}"> 16 <DataGrid.Columns> 17 <DataGridTextColumn Width="150" Binding="{Binding Name}" Header="名前" /> 18 <DataGridTextColumn Width="100" Binding="{Binding Age}" Header="年齢"> 19 <DataGridTextColumn.CellStyle> 20 <Style TargetType="{x:Type DataGridCell}"> 21 <Setter Property="BorderThickness" Value="4" /> 22 <Style.Triggers> 23 <Trigger Property="IsSelected" Value="True"> 24 <Setter Property="Background" Value="#87CEEB" /> 25 <Setter Property="Foreground" Value="Black" /> 26 </Trigger> 27 <DataTrigger Binding="{Binding IsEditItem}" Value="True"> 28 <Setter Property="BorderBrush" Value="Red" /> 29 </DataTrigger> 30 <DataTrigger Binding="{Binding DataContext.IsEditMain, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Value="True"> 31 <Setter Property="Foreground" Value="Red" /> 32 </DataTrigger> 33 </Style.Triggers> 34 </Style> 35 </DataGridTextColumn.CellStyle> 36 </DataGridTextColumn> 37 <DataGridTemplateColumn Header="IsEditItem"> 38 <DataGridTemplateColumn.CellTemplate> 39 <DataTemplate> 40 <CheckBox VerticalContentAlignment="Center" IsChecked="{Binding IsEditItem, UpdateSourceTrigger=PropertyChanged}" /> 41 </DataTemplate> 42 </DataGridTemplateColumn.CellTemplate> 43 </DataGridTemplateColumn> 44 </DataGrid.Columns> 45 </DataGrid> 46 </DockPanel> 47</Window>

cs

1using System.Collections.ObjectModel; 2using System.Windows; 3using Livet; 4 5namespace Questions241295 6{ 7 public partial class MainWindow : Window 8 { 9 public MainWindow() => InitializeComponent(); 10 } 11 12 public class MainWindowViewModel : ViewModel 13 { 14 public ObservableCollection<Item> Items { get; } 15 16 public bool IsEditMain { get => isEdit; set => RaisePropertyChangedIfSet(ref isEdit, value); } 17 private bool isEdit; 18 19 public MainWindowViewModel() 20 { 21 Items = new ObservableCollection<Item> 22 { 23 new Item("a", 24), 24 new Item("b", 25), 25 }; 26 } 27 } 28 29 public class Item : ViewModel 30 { 31 public string Name { get => name; set => RaisePropertyChangedIfSet(ref name, value); } 32 private string name; 33 34 public int Age { get => age; set => RaisePropertyChangedIfSet(ref age, value); } 35 private int age; 36 37 public bool IsEditItem { get => isEdit; set => RaisePropertyChangedIfSet(ref isEdit, value); } 38 private bool isEdit; 39 40 public Item(string name, int age) => (Name, Age) = (name, age); 41 } 42}
  • IsEditItem 個々のIsEdit(ボーダー赤)
  • IsEditMain 全体のIsEdit(文字赤)

アプリ画像

投稿2020/02/14 11:56

編集2023/07/20 14:05
TN8001

総合スコア9801

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Coriander

2020/02/15 00:42

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

0

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

投稿2020/02/14 06:13

hihijiji

総合スコア4152

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Coriander

2020/02/15 00:44

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問