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

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

ただいまの
回答率

88.04%

Visual Treeの要素を取得したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,659
退会済みユーザー

退会済みユーザー

Windows7、Visual Studio 2013、WPFで開発しています。 
Visual Treeの要素を取得するのに、http://blog.xin9le.net/entry/2013/10/29/222336を使ってみました。

これってnamespaceはどう設定するものでしょう?
アドバイスいただけたらうれしいです。

namespace WpfApplication9 {
    public partial class MainWindow : Window {
のときに。

namespaceを同じにしても動かなかったのです。
よろしくお願いします。

コードは、URL先のものそのままで、

public static class DependencyObjectExtensions
の上に

namespace WpfApplication9{
public static class DependencyObjectExtensions
{

と書き足したのと、

private void button_Click(){
var button = window                  //--- Windowの
           .Descendants<Button>()    //--- ボタン型の子孫要素のうち
           .Where(x => x.IsEnabled)  //--- 有効なボタンの
           .FirstOrDefault();        //--- 最初に見つかったものを取得
}

のように、ボタンクリックにメソッドを割り当てたことです。
これで、windowがないので、

private void button_Click(){
Window window = Application.Current.MainWindow;
var button = window                  //--- Windowの
           .Descendants<Button>()    //--- ボタン型の子孫要素のうち
           .Where(x => x.IsEnabled)  //--- 有効なボタンの
           .FirstOrDefault();        //--- 最初に見つかったものを取得
}

としました。
これで、.Whereの行で、そのようなものがないというようなエラーになりました。

できれば、namespaceは分けて、namespace searchChildrenとかにして、複数の異なるprojectから使いたい、と思っています。
その場合に、この
var button = window
をどう設定すればよいのか、ということもご示唆いただければうれしいです。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Tak1wa

    2016/03/04 18:02

    現在のコードを記載してください。その上でどこが間違っているのか聞いたほうが早いと思います。方向性としてはVisualTreeHelperを使うことであってます。

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2016/03/05 12:20

    いつもありがとうございます。
    追記しました。

    キャンセル

回答 1

checkベストアンサー

+1

動かなかったとはどのような症状でしょうか?

URL先で書かれている静的クラスDependencyObjectExtensionsはnamespaceが同じで問題ありません。
また、異なるnamespaceであってもusing文を記載すれば良いだけです。

この静的クラスで定義されているChildrenやDescendantsは「拡張メソッド」と呼ばれるものです。

使い方は簡単で今回はDependencyObjectクラスにあたかも追加のメソッドを定義しているようなものになります。

例えば以下のようにしてWindow内の全ての子孫要素を列挙できます。
LINQを組み合わせて使うことが多いでしょう。

//ステップ実行してdescendantsの中を確認してみてください。
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var descendants = this.Descendants();

            //以下略

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/03/05 13:38

    ありがとうございます。ずばりそれでした。
    呼び出し側にusing System.Linqがありませんでした。

    それで呼び出せるようにはなったのですが、今度は、windowを取得するところで失敗しています。

    ウィンドウがふたつ(MainWindowとSubWindow)があります。

    namespace WpfApplication9{
    public class MainWindow: Window {
    WpfApplication9.SubWindow subwindow = new WpfApplication9.SubWindow();
    public MainWindow() {
    InitializeComponent();
    subwindow.Show();
    }

    private void button_Click(){
    Window window = Application.Current.MainWindow;
    var button = window //--- Windowの
    .Descendants<Button>() //--- ボタン型の子孫要素のうち
    .Where(x => x.IsEnabled) //--- 有効なボタンの
    .FirstOrDefault(); //--- 最初に見つかったものを取得
    }

    という感じです。
    これで、button_Clickすると、windowには、メインのウィンドウではなく、subwindowが入ってしまいます。
    MainWindowを取得するにはどのようにしたらよいでしょうか?

    キャンセル

  • 2016/03/05 16:43

    thisでいけました。
    逆にSubwindowが複数ある場合には、どう特定すればよいのでしょう。
    Subwindowはthisのここうもくなのかな。

    キャンセル

  • 2016/03/05 17:09

    thisについてはWPFとは関係なくC#の現在のインスタンスを指す機能です。対象のWindow継承クラス内で自Windowを指したいのであればthisで良いでしょう。

    直接別のWindowを操作するのはお勧めできませんが、現在LoadされているWindowについてはApp.Current.Windows.OfType<Window>()
    で列挙できるためLINQで簡単に取得することは可能です。

    たとえばアクティブなWindowの取得したい場合は以下のように。
    var win = App.Current.Windows.OfType<Window>().FirstOrDefault(w => w.IsActive);
    //場合によっては見つからない可能性の考慮も必要です。

    なお、既に主題に書かれた問題は解決して別の質問内容になっているように思えます。
    別の質問についてはコメントではなく新たに記載した方が良いです。

    キャンセル

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

  • ただいまの回答率 88.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る