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

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

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

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

WPF

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

Q&A

解決済

1回答

8500閲覧

親ユーザーコントロールにあるx:Name属性をコードビハインドから指定するには

tride

総合スコア68

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

WPF

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

1グッド

0クリップ

投稿2019/11/22 01:10

表題の通りですが、入れ子になったユーザーコントロールにある子ユーザーコントロール(以下PageTop.xaml)の"TestButton"から、親に当たるユーザーコントロールのAllViewWindow.xamlのStackpanelPageTopを、コード側から操作するにはどうすればいいでしょうか。
以下のようにFindNameで探してもNullになります。

C#

1StackPanel stackPanelPageTop = (StackPanel)FindName("StackpanelPageTop"); //Nullになる

<MainWIndow.xaml>

xaml

1<Window x:Class="AppWPF.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:page="clr-namespace:AppWPF.UserControlObjects.Page" 7 8 <Grid> 9 <page:AllViewWindow/> 10 </Grid> 11</Window> 12

<AllViewWindow.xaml>

xaml

1<UserControl x:Class="AppWPF.UserControlObjects.Page.AllViewWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:page="clr-namespace:AppWPF.UserControlObjects.Page" 7 mc:Ignorable="d" > 8 <Grid> 9 <StackPanel x:Name="StackpanelPageTop" Margin="0" Visibility="Visible" Opacity="1"> 10 <page:PageTop VerticalAlignment="Stretch"/> 11 </StackPanel> 12 </Grid> 13</UserControl>

<PageTop.xaml>

xaml

1<UserControl x:Class="AppWPF.UserControlObjects.Page.PageTop" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 mc:Ignorable="d" 7 Stylus.IsPressAndHoldEnabled="False" HorizontalAlignment="Center" VerticalAlignment="Center" Width="1507"> 8 9 <StackPanel x:Name="CanvasTop" Margin="0,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Center"> 10 <Button x:Name="TestButton" Width="100" Height="50" Click="TestButton_Click" /> 11 12 </StackPanel> 13</UserControl> 14

C#

1using System.Windows.Controls; 2using AppWPF.UserControlObjects.Motion; 3 4namespace AppWPF.UserControlObjects.Page 5{ 6 /// <summary> 7 /// Page_Top.xaml の相互作用ロジック 8 /// </summary> 9 public partial class PageTop : UserControl 10 { 11 public PageTop() 12 { 13 InitializeComponent(); 14 } 15 16 17 private void TestButton_Click(object sender, System.Windows.RoutedEventArgs e) 18 { 19 //ここでAliiViewWindowのStackpanelPageTopを指定したい 20 //StackpanelPageTop.Visibility = Visibility.Hidden;など 21 } 22 } 23} 24
TN8001👍を押しています

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

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

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

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

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

Zuishin

2019/11/22 01:13

回答者を選んで恣意的にベストアンサーをつける質問者なので答える気になりません。
tride

2019/11/22 01:48

質問の内容と違う内容の回答はお控えください。 また、答える気にならないのであれば、スルーをお願いします。
Zuishin

2019/11/22 01:51

他の回答者が回答するときに参考になる情報です。
guest

回答1

0

ベストアンサー

FindNameは配下(子供方向)の要素しか探せません。
提示のxamlであればvar stackPanelPageTop = (StackPanel)Parent;で取れますね。


できれば子供から親を操作するのは避けたほうが良いと思います。
(子供と親が不可分でもっといろいろな操作がある場合、その限りではありません)

今回の場合は、↓とすれば子供は親を気にする必要はなくなります。

xml:AllViewWindow.xaml

1<UserControl 2 x:Class="AppWPF.UserControlObjects.Page.AllViewWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:page="clr-namespace:AppWPF.UserControlObjects.Page"> 6 <StackPanel Visibility="{Binding PageVisibility, ElementName=PageTop}"> 7 <page:PageTop x:Name="PageTop" /> 8 </StackPanel> 9</UserControl>

cs:PageTop.xaml.cs

1using System.Windows; 2using System.Windows.Controls; 3 4namespace AppWPF.UserControlObjects.Page 5{ 6 public partial class PageTop : UserControl 7 { 8 public Visibility PageVisibility 9 { 10 get => (Visibility)GetValue(PageVisibilityProperty); 11 set => SetValue(PageVisibilityProperty, value); 12 } 13 public static readonly DependencyProperty PageVisibilityProperty = 14 DependencyProperty.Register(nameof(PageVisibility), typeof(Visibility), typeof(PageTop), 15 new PropertyMetadata(Visibility.Visible)); 16 17 public PageTop() => InitializeComponent(); 18 private void TestButton_Click(object sender, RoutedEventArgs e) 19 => PageVisibility = Visibility.Hidden; 20 } 21}

追記 VisualTreeHelper参考コード

cs:PageTop.xaml.cs

1var stackpanelPage01 = Window.GetWindow(this).FindChild<StackPanel>("StackpanelPage01");

cs:DependencyObjectExtensions.cs

1using System.Windows; 2using System.Windows.Media; 3 4namespace AppWPF 5{ 6 internal static class DependencyObjectExtensions 7 { 8 public static T FindChild<T>(this DependencyObject parent, string childName) where T : FrameworkElement 9 { 10 if(parent == null) return null; 11 12 var childrenCount = VisualTreeHelper.GetChildrenCount(parent); 13 for(var i = 0; i < childrenCount; i++) 14 { 15 var child = VisualTreeHelper.GetChild(parent, i); 16 if(child is FrameworkElement frameworkElement && frameworkElement.Name == childName) 17 { 18 return (T)frameworkElement; 19 } 20 else 21 { 22 var foundChild = FindChild<T>(child, childName); 23 if(foundChild != null) 24 { 25 return foundChild; 26 } 27 } 28 } 29 30 return null; 31 } 32 } 33}

How can I find WPF controls by name or type? - Stack Overflow

投稿2019/11/22 02:36

編集2023/08/09 09:18
TN8001

総合スコア9326

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

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

tride

2019/11/22 03:30

parentで思っていたことができました! 今回は親と子が不可分でいろいろな操作があるので、これで行こうと思います。 ですが頂いたソースは言われて初めて気づいたといいますか、目からうろこでした。 属性でバインドしてやるのは、別件で使えそうで助かります。 ただ1点気になるのが、今回の場合で以下コードのように親の他のコントロール(StackpanelPage01)を操作したい場合、さらに親を取得してからその子を探すというやり方でよかったのでしょうか? なんだか、まどろっこしい感じでもやっとしてます。 ※親のGridに名前を追記しました。 <AllViewWindow.xaml> <Grid x:Name="GridAllView"> <StackPanel x:Name="StackpanelPageTop" Margin="0" Visibility="Visible" Opacity="1"> <page:PageTop VerticalAlignment="Stretch"/> </StackPanel> <StackPanel x:Name="StackpanelPage01" Margin="0" VerticalAlignment="Stretch" Visibility="Hidden" Opacity="0"> <page:Page01 VerticalAlignment="Stretch" Height="868" /> </StackPanel> </Grid> <PageTop.xaml.cs> //親を取得 var stackPanelPageTop = (StackPanel)Parent; //親の親'を取得 var gridAllView = (Grid)stackPanelPageTop.Parent; //親'の子であるStackpanelPage01を取得 var stackpanelPage01 = (StackPanel)gridAllView.FindName("StackpanelPage01");
TN8001

2019/11/22 04:07

基本的にはそうなります。 レイアウトが変化しないのであれば、Loadedイベントあたりでメンバ変数に入れておき、毎回取得しないようにすればすっきりはしそうです。 名前が被っていなければ var stackpanelPage01 = (StackPanel)Window.GetWindow(this).FindName("StackpanelPage01"); でも取れます。
TN8001

2019/11/22 04:21

失礼しました。 GetWindowでは取れないですね。
tride

2019/11/22 04:34

追加質問への回答ありがとうございます。 名前がユニークなのでいけるかなと思いましたが、残念です。 Loadedイベントへのメンバ変数に入れる件に関しては、現在考えているのでも一考の余地がありそうです。 改めて検討してみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問