WPF初心者です。
題名の通り、子要素ラベルのcontentを簡単に取得できる方法はありますでしょうか?
なるべくテンプレートなどを使わない方法&FindNameなどの、文字列を検索しない方法のものを探しています。
Buttonコントロール自体にcontentは入れない方法でお願いします。
該当のソースコード
xaml
1<Button x:Name="BTN"> 2 <Canvas> 3 <Label x:Name="LBL" Content="ラベルのテキスト" /> 4 </Canvas> 5</Button>
C#
1//string label_text = ?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
ベストアンサー
例のxamlがイレギュラーなのでしたいことをくみ取れている自信はありませんが、探しているのはVisualTreeHelper
ですかね?
xml
1<Window 2 x:Class="Questions299424.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="800" 6 Height="450" 7 Loaded="Window_Loaded"> 8 <Grid> 9 <Button x:Name="BTN" Click="BTN_Click"> 10 <Canvas> 11 <Label x:Name="LBL" Content="ラベルのテキスト" /> 12 </Canvas> 13 </Button> 14 </Grid> 15</Window>
cs
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Windows; 5using System.Windows.Controls; 6using System.Windows.Media; 7 8namespace Questions299424 9{ 10 public partial class MainWindow : Window 11 { 12 public MainWindow() 13 { 14 InitializeComponent(); 15 16 // こういうことじゃないんですよね? 17 string label_text = (string)LBL.Content; 18 19 // 構造が固定で決め打ちでいいならこう? 20 string label_text2 = (string)((Label)((Canvas)BTN.Content).Children[0]).Content; 21 22 // ↑キャストの順が逆に見えて直感的じゃないのでこうのほうが見やすい? 23 string label_text3 = ((BTN.Content as Canvas).Children[0] as Label).Content as string; 24 25 // 構造が違ってもエラーは出ないようにする(もちろん違ったら取得もできない) 26 string label_text4 = (BTN.Content as Canvas)?.Children.OfType<Label>().FirstOrDefault()?.Content as string; 27 28 // この時点ではVisualTreeが出来てないのでまだ取れない 29 string label_text5 = BTN.Descendants<TextBlock>().FirstOrDefault()?.Text; 30 } 31 32 private void Window_Loaded(object sender, RoutedEventArgs e) 33 { 34 // Loaded以降ならOK 35 string label_text = BTN.Descendants<TextBlock>().FirstOrDefault()?.Text; 36 } 37 38 private void BTN_Click(object sender, RoutedEventArgs e) 39 { 40 if(sender is Button button) 41 { 42 // Buttonの子孫で最初に見つかったLabelのContent 43 string label_text = button.Descendants<Label>().FirstOrDefault()?.Content as string; 44 45 // ならいっそTextBlockを探す 46 string label_text2 = button.Descendants<TextBlock>().FirstOrDefault()?.Text; 47 } 48 } 49 } 50 51 // [VisualTreeの子孫要素を取得する - xin9le.net](https://blog.xin9le.net/entry/2013/10/29/222336) 52 public static class DependencyObjectExtensions 53 { 54 //--- 子要素を取得 55 public static IEnumerable<DependencyObject> Children(this DependencyObject obj) 56 { 57 if(obj == null) throw new ArgumentNullException("obj"); 58 59 var count = VisualTreeHelper.GetChildrenCount(obj); 60 if(count == 0) yield break; 61 62 for(var i = 0; i < count; i++) 63 { 64 var child = VisualTreeHelper.GetChild(obj, i); 65 if(child != null) yield return child; 66 } 67 } 68 69 //--- 子孫要素を取得 70 public static IEnumerable<DependencyObject> Descendants(this DependencyObject obj) 71 { 72 if(obj == null) throw new ArgumentNullException("obj"); 73 74 foreach(var child in obj.Children()) 75 { 76 yield return child; 77 foreach(var grandChild in child.Descendants()) 78 yield return grandChild; 79 } 80 } 81 82 //--- 特定の型の子要素を取得 83 public static IEnumerable<T> Children<T>(this DependencyObject obj) 84 where T : DependencyObject => obj.Children().OfType<T>(); 85 86 //--- 特定の型の子孫要素を取得 87 public static IEnumerable<T> Descendants<T>(this DependencyObject obj) 88 where T : DependencyObject => obj.Descendants().OfType<T>(); 89 } 90}
参考
VisualTreeの子孫要素を取得する - xin9le.net
なるべくテンプレートなどを使わない方法&FindNameなどの、文字列を検索しない方法のものを探しています。
Buttonコントロール自体にcontentは入れない方法でお願いします。
やりたいことを説明するのが難しいのかもしれませんが、初心者という自覚があるなら最初から手法を制限されないほうがよろしいかと思います。
もっと良い方法があっても提案できません(この件でもっと良い方法があるかはわかりません^^;
投稿2020/10/21 12:04
編集2023/07/23 08:13総合スコア9862
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/10/22 01:12