none
Gridの子要素の取得方法【XAML】【C#】 RRS feed

  • 質問

  • XAMLでGridに追加した複数の子要素をC#でまとめて操作したいのですが、子要素の取得方法(x:Name以外)が分かりません。

    例えば下記のGrid内の各TextBlockのTextプロパティをZにする場合にはどんな方法がありますか?

    <Grid x:Name="SampleGrid">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
    
        <TextBlock x:Name="tb1" Grid.Row="0" Grid.Column="0" FontSize="50" Text="A"/>
        <TextBlock x:Name="tb2" Grid.Row="0" Grid.Column="1" FontSize="50" Text="B"/>
        <TextBlock x:Name="tb3" Grid.Row="1" Grid.Column="0" FontSize="50" Text="C"/>
        <TextBlock x:Name="tb4" Grid.Row="1" Grid.Column="1" FontSize="50" Text="D"/>
    </Grid>
    

    現状ですとx:Nameを使って下記のように変更する方法しか知りません。

    tb1.Text = "Z";
    tb2.Text = "Z";
    tb3.Text = "Z";
    tb4.Text = "Z";
    
    もっとスマートな方法をご存知の方がいらっしゃったら、是非とも教えてください!よろしくお願いします。
    2015年1月20日 15:23

回答

すべての返信

  • こんにちは。

    LogicalTreeHelperを使ってはどうでしょう。

    foreach(var child in LogicalTreeHelper.GetChildren(SampleGrid))
    {
        if (child is TextBlock)
        {
            ((TextBlock)child).Text = "Z";
        }
    }

    2015年1月20日 15:41
    モデレータ
  • // ストアアプリにLogicalTreeHelperって含まれてたっけ?

    foreach (var textBlock in SampleGrid.Children.OfType<TextBlock>()) {
        textBlock.Text = ...
    }
    2015年1月21日 1:38
  • データバインドを使いましょう!
    http://www.atmarkit.co.jp/ait/articles/1311/01/news095_2.html
     
    それはさておき。
    Windows ランタイム アプリのコードで XAML の子要素を探し出すには、VisualTreeHelper クラス (Windows.UI.Xaml.Media 名前空間) を使います。
    https://social.msdn.microsoft.com/Forums/netframework/ja-JP/5d40d7d0-8220-4714-bc5e-bb8807e2cfe9/button?forum=winstoreapp

    なお、Panel クラスを継承している Grid クラスなどでは、Hongliang さんが書いてくれたように Children プロパティを使って直下の子要素を列挙できます。


    biac [ http://bluewatersoft.cocolog-nifty.com/ ]


    • 編集済み biacMVP 2015年1月21日 2:11 Children プロパティについて追記
    • 回答としてマーク HayaUp 2015年1月21日 13:50
    2015年1月21日 2:01
  • 「XAMLでGridに追加した複数の子要素をC#でまとめて操作したい」 かつ 「もっとスマートな方法」 をお望みなら、biac さんの仰るとおり、データバインドを使うのが一番だと思います。

        <TextBlock Text="{Binding TextA}" />
        <TextBlock Text="{Binding TextB}" />
        <TextBlock Text="{Binding TextC}" />
        <TextBlock Text="{Binding TextD}" />


    「不適切な発言」の濫用はフォーラムの運営を妨げる行為です。ご遠慮ください https://social.msdn.microsoft.com/Forums/ja-JP/0f7b0966-0141-4c1b-b7b9-aed65abf60b6?forum=announceja

    2015年1月21日 2:15
  • WPFと勘違いしておりました。失礼しました。
    ご指摘のとおりWinRTではLogicalTreeHelperは使えません。
    2015年1月21日 2:19
    モデレータ
  • 皆さん、質問に答えてくださりありがとうございます。

    1つ理解が深まり嬉しいです。

    biacさんが教えてくれた VisualTreeHelper を使ったコードが通りましたので貼ります。

    public void SampleFunction()
    {
        int count = VisualTreeHelper.GetChildrenCount(SampleGrid);
                
        for (int i = 0; i < count; i++)
        {
            var sg_child = VisualTreeHelper.GetChild(SampleGrid, i);
    
            if (sg_child.GetType() == typeof(TextBlock))
            {
                TextBlock tb = (TextBlock)sg_child;
                tb.Text = "Z";
            }
        }
    }
    
    データバインドを使った方法はこれから勉強します。必要に応じて使い分けられるように励みます。
    2015年1月21日 14:10