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

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

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

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

Q&A

0回答

2545閲覧

編集していないDataGridTextColumnのセルの文字列を書き換えたい

yonotsui

総合スコア28

C#

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

0グッド

1クリップ

投稿2019/03/03 08:42

編集2019/03/05 19:06

ApplicationのResourceにDataGridのStyleを定義して、DataGridTextColumnのDataGridCellを外部から文字列を書き換えられるようにできないでしょうか。

文字列を書き換えるために、DataGridCellのContentPresenter.Content.Textをソースとした双方向(Mode=TwoWay)のBindingを作成して添付プロパティにバインディングしています。
DataGridCellは編集していない時はTextBlock、編集しているときはTextBoxをContentPresenter.ContentがもっているのでおなじPathでそれぞれのTextにBindingできます。
ソース上からBinding.Targetの添付プロパティを書き換えることで、Binding.SourceのTextBox・TextBlockのTextを操作しています。

Cellを編集しているときのTextBoxのTextを書き換えた時はDataGridCellの値も書き換わります。
しかし、Cellを編集していない時のTextBlockのTextは書き換えてもCellの値には影響しません。
TextBlockが文字を表示するときに内部で使用するBinding.ModeがOneWayのため、Textを書き換えても影響しないようです。

このTextBlockのTextとDataGridCellを双方向にBindingできれば、解決するかと思っています。
すべてのDataGridに対して修正を行いため、ApplicationのResourceに修正のためのDataGridのデフォルトStyleを定義して対応したいと考えているのですが、対応方法が思い浮かびません。

試してはいませんが、列ごとのセルのスタイル「DataGridTextColumn.ElementStyle」をつかってContentTemplateを定義すれば双方向BindingのTextBlockを作成できるかもしれません。
ですがDataGridTextColumnは自分自身のStyleをもたないため、Resourceの中でデフォルトStyleを定義することができません。
だからDataGridTextColumn.ElementStyleを使った対応は断念しました。

ApplicationのResourceにDataGridのStyleを定義して、DataGridTextColumnのDataGridCellを外部から文字列を書き換えられるようにできないでしょうか。
私にはResourceにデフォルトのStyleを定義するぐらいしか思いつきませんが、他に解決方法があるのならそちらでもかまいません。
ご教示いただけると幸いです。

データソースを変更して、表示の更新(同期)を行っても表示は変わりませんか?

たしかに各Cellにはデータソース(DataGridTextColumn.Binding)があるので、ソースを直接編集すれば対応は簡単です。
しかし、同様の処理を行いたい箇所は多義にわたるので局所的な対応はしたくありません。
汎用的な処理で吸収したいと考えております。

-xaml

<Style x:Key="DataGridLinkTextStyle" TargetType="DataGridCell"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type DataGridCell}"> <Border x:Name="border" BorderBrush="Transparent" BorderThickness="1" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition Width="auto"/> </Grid.ColumnDefinitions> <ContentPresenter x:Name="presenter" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> <!--LinkButtonsは内部でLinkButtons.TextにBindingしたソースを書き換えます--> <link:LinkButtons Grid.Column="1" UseType="{Binding Path=Column.(local:DataGridLinkTextColumnStyle.UseType),RelativeSource={RelativeSource AncestorType=DataGridCell,Mode=FindAncestor}}"> <link:LinkButtons.Style> <Style TargetType="link:LinkButtons"> <!--ContentPresenter.Content.TextをソースにしたBindingを作成します--> <Setter Property="Text" Value="{Binding Path=Content.Text,ElementName=presenter}"/> </Style> </link:LinkButtons.Style> </link:LinkButtons> </Grid> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>

-xaml.cs

public partial class LinkButtons : ItemsControl { public static readonly System.Windows.DependencyProperty TextProperty = DependencyProperty.Register( nameof(Text), typeof(String), typeof(LinkButtons),new FrameworkPropertyMetadata("",FrameworkPropertyMetadataOptions.BindsTwoWayByDefault) ); /// <summary> /// テキスト /// </summary> public String Text { get => (String)GetValue(TextProperty); set => SetValue(TextProperty, value); } void Hoge() { Text = "代入後、TextBox/TextBlockのTextも変わる。"+ "TextBoxの場合はBindingがTwoWayなのでCellの値も変わり、TextBlockの場合はOneWayなのでCellの値が変わらない"; }

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

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

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

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

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

moredeep

2019/03/05 07:46

すみませんが、質問内容がよくわからないです。 >編集しているときのTextBoxからはCellの値を書き換えることはできるのですが、編集していない時のTextBlockはTextを書き換えてもCellに反映させることができません。 これは、編集した内容が、確定したら無くなってしまうという意味でしょうか?それとも、UIからは編集できるが、コードからは変更できないという意味でしょうか? 後者であれば、そのコードを見てみないとなんとも言えないかと思います。
pepperleaf

2019/03/05 14:06

WPFは試したことが無いですが、 データソースを変更して、表示の更新(同期)を行っても表示は変わりませんか? Formだと、OKでしたが。
yonotsui

2019/03/05 19:14 編集

言葉足らずですみません。 >これは、編集した内容が、確定したら無くなってしまうという意味でしょうか? DataGridCellがもつTextBlockは内部でCellの値とBindingしていますが、CellからTextBlockへの一方向のためTextBlock.Textに値を設定してもCellに影響しません。 どうにかして編集していない時のCellの値を書き換えたいです。 >データソースを変更して、表示の更新(同期)を行っても表示は変わりませんか? データソースだと個別に設定する処理を書かないといけないので、あまりやりたくはありません。 だからDataGridに対しての修正だけですべて解決したいです。
Zuishin

2019/03/05 19:53

問題をこちらで確認するために色々と補わなければなりませんが、そうではなくやりたいことを表現するコンパイル可能な最低限のソース(やっていることの全ソースではありません。コンパイル可能な状態を維持しつつ問題が再現する最小限まで削ってください)と、問題が再現する手順を書いてください。
moredeep

2019/03/06 04:39

仰りたいことはわかりますが、「こうするとどうなりますか?」という質問に対しては、「どうなるか」を回答してほしいです。それを採用できない理由があるならば、そのうえで「でもこういう理由で・・・」と書けばいいのではないかなと。 仕様に沿っていないことは承知のうえで、問題がどこにあるかを探るために試してもらっている場合もありますし、その結果から他に何か得られることもあります。まぁ今回は仕様が追加されたわけですが。 ところで、質問文に出てくる「Cellの値」とは何を指していますか?DataGridにBindしたVMで持っている値ですか?それとも、Cellに表示されている文字列のみを指しますか? (「Cellの値」とは、VM - Content.Text - TextBox/TextBlock.Textのうちのどれを指しているのか?)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問