質問するログイン新規登録
C#

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

WPF

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

Q&A

解決済

2回答

2054閲覧

WPFコントロールの子孫要素の設定方法について

yutk

総合スコア6

C#

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

WPF

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

1グッド

0クリップ

投稿2020/01/17 01:42

編集2020/01/17 01:44

1

0

お世話になっております。

C#のWPFで子孫要素を取得する方法についてお教えいただきたいのですが、
以下のようなxaml上でViewboxの定義をし、Viewboxの子孫要素であるPathの値を変更したい場合の
実現方法方法を教えていただきたいです。

xaml

1<Viewbox x:Key="testCanvasImage"> 2 <Canvas Width="20" Height="20"> 3 <Canvas> 4 <Canvas.RenderTransform> 5 <TranslateTransform X="0" Y="0"/> 6 </Canvas.RenderTransform> 7 <Canvas> 8 <Canvas.RenderTransform> 9 <MatrixTransform Matrix=""/> 10 </Canvas.RenderTransform> 11         <!-- この値を変更したい --> 12 <Path Fill="#000000" StrokeThickness="0"> 13 <Path.Data> 14 <PathGeometry Figures=""/> 15 </Path.Data> 16 </Path> 17 <!-- この値を変更したい --> 18 </Canvas> 19 </Canvas> 20 </Canvas> 21</Viewbox>

単純にViewboxの子要素であるPathを変更する場合は、以下のようなコードで設定できるかと思います。

xaml

1<Viewbox x:Key="testCanvasImage"> 2 <Path Fill="#FFFFFF" Stretch="Fill"/> 3</Viewbox>

c#

1this.viewBox = new ViewBox() 2this.viewBox = FindResource(testCanvasImage) as ViewBox; 3 4Path path = this.viewBox.Child as Path; 5if ( path != null ) 6{ 7 path.Fill = #000000; 8}

何卒宜しくおねがいします。

TN8001👍を押しています

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

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

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

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

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

Zuishin

2020/01/18 02:52

Path に x:Name を付ければいいのでは?
guest

回答2

0

ベストアンサー

愚直に書くとだるいですね。
子孫探索にはLogicalTreeHelperVisualTreeHelperがあります(詳細は調べてください)
あまり使いやすくないので拡張メソッドにしておくと楽でいいです。

xml

1<Window 2 x:Class="Questions235664.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 5 <Window.Resources> 6 <Viewbox x:Key="testCanvasImage"> 7 <Canvas> 8 <Canvas> 9 <Canvas> 10 <Path Fill="#000000" StrokeThickness="0"> 11 <Path.Data> 12 <PathGeometry Figures="" /> 13 </Path.Data> 14 </Path> 15 <Path x:Name="Path2" Fill="#FFFFFF" /> 16 </Canvas> 17 </Canvas> 18 </Canvas> 19 </Viewbox> 20 </Window.Resources> 21</Window>

cs

1using System; 2using System.Collections.Generic; 3using System.Diagnostics; 4using System.Linq; 5using System.Windows; 6using System.Windows.Controls; 7using System.Windows.Media; 8using System.Windows.Shapes; 9 10namespace Questions235664 11{ 12 public partial class MainWindow : Window 13 { 14 public MainWindow() 15 { 16 InitializeComponent(); 17 18 var viewBox = FindResource("testCanvasImage") as Viewbox; 19 20 // 愚直に書くと 21 var canvas1 = viewBox.Child as Canvas; 22 var canvas2 = canvas1.Children[0] as Canvas; 23 var canvas3 = canvas2.Children[0] as Canvas; 24 var path = canvas3.Children[0] as Path; 25 Debug.WriteLine(path.Fill); 26 27 // 便利拡張メソッド使用 28 path = viewBox.Descendants<Path>().First(); 29 Debug.WriteLine(path.Fill); 30 31 // 子孫に探し物が複数ある場合Nameかなんかを付けておく 32 path = viewBox.Descendants<Path>().First(x => x.Name == "Path2"); 33 Debug.WriteLine(path.Fill); 34 } 35 } 36 37 // https://blog.xin9le.net/entry/2013/10/29/222336 38 static class DependencyObjectExtensions 39 { 40 public static IEnumerable<DependencyObject> Children(this DependencyObject obj) 41 { 42 if(obj == null) throw new ArgumentNullException(nameof(obj)); 43 44 var count = VisualTreeHelper.GetChildrenCount(obj); 45 if(count == 0) yield break; 46 47 for(var i = 0; i < count; i++) 48 { 49 var child = VisualTreeHelper.GetChild(obj, i); 50 if(child != null) yield return child; 51 } 52 } 53 public static IEnumerable<DependencyObject> Descendants(this DependencyObject obj) 54 { 55 if(obj == null) throw new ArgumentNullException(nameof(obj)); 56 57 foreach(var child in obj.Children()) 58 { 59 yield return child; 60 foreach(var grandChild in child.Descendants()) 61 yield return grandChild; 62 } 63 } 64 public static IEnumerable<T> Children<T>(this DependencyObject obj) where T : DependencyObject 65 => obj.Children().OfType<T>(); 66 public static IEnumerable<T> Descendants<T>(this DependencyObject obj) where T : DependencyObject 67 => obj.Descendants().OfType<T>(); 68 } 69}

参考 VisualTreeの子孫要素を取得する - xin9le.net

投稿2020/01/18 02:38

編集2023/07/18 21:23
TN8001

総合スコア10166

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

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

yutk

2020/01/18 04:01

わかりやすくご回答いただきありがとうございました。 こちらの方法で実施してみたいと思います。 ありがとうございました!
guest

0

ViewBoxのChildの CanvasのChildの CanvasのChildの CanvasのChildのPathを変更してください。
入れ子の深さが任意なら再帰メソッドを書くと良いでしょう。

投稿2020/01/17 03:00

hihijiji

総合スコア4152

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

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

yutk

2020/01/17 06:58

ご回答ありがとうございます。 子要素を辿っていき取得するのはわかりましたが コードで記載する方法がわかりませんでした。。。
hihijiji

2020/01/18 01:28

貴殿が書いてみたコードで動かない場合は、提示していただければ相談にのれるかもしれません。 丸投げは受け付けません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問