5

したがって、以下のサンプルコードでは、メインウィンドウWindow1.xamlの子であるUserControlUserControldChildを作成します。FindName()メソッドが以下のコードで「myButton」を見つけられないのはなぜですか?

これはWPFXAMLNameScopesと関係があるはずですが、 NameScopeがどのように機能するかについての適切な説明はまだ見つかりません。誰かが私を啓発できますか?

//(xml) Window1.xaml    
<Window x:Class="VisualTreeTestApplication.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:VisualTreeTestApp="clr-namespace:VisualTreeTestApplication"
    Title="Window1" Height="400" Width="400">
    <Grid>
        <VisualTreeTestApp:UserControlChild/>
    </Grid>
</Window>

//(c#) Window1.xaml.cs
namespace VisualTreeTestApplication
{
  /// <summary>
  /// Interaction logic for Window1.xaml
  /// </summary>
  public partial class Window1 : Window
  {
    public Window1()
    {
      InitializeComponent();
      Button btnTest = (Button)Application.Current.MainWindow.FindName("myButton");
      // btnTest is null!
    }
  }
}

以下のUserControl:

//(wpf) UserControlChild.xaml
<UserControl x:Class="VisualTreeTestApplication.UserControlChild"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">
    <Grid x:Name="myGrid">      
        <Button x:Name="myButton" Margin="20" >Button</Button>
    </Grid>
</UserControl>

//(c#) UserControlChild.xaml.cs (no changes)
namespace VisualTreeTestApplication
{
  /// <summary>
  /// Interaction logic for UserControlChild.xaml
  /// </summary>
  public partial class UserControlChild : UserControl
  {
    public UserControlChild()
    {
      InitializeComponent();
    }
  }
}

これが適切に回答されない場合は、ここの投稿に記載されているFindName()を使用する代わりの方法を見つけました。

4

1 に答える 1

5

あなたは正しいです - これは XAML 名前スコープに関係しています。

これは、XAML Namescopes ページの Name related APIs セクションに(やや不十分ですが) 記載されています。

基本的に、FrameworkElement または FrameworkContentElement がある場合は、独自の名前スコープを定義します。名前スコープを持たない型で FindName() を呼び出すと、WPF は名前スコープを定義する要素が見つかるまでツリーを検索し、次にその名前スコープ内を検索します

あなたの場合、ウィンドウの名前スコープで検索しています(これは FrameworkContentElement なので、独自のスコープを定義します)。そのスコープで定義された要素を検索するだけです。

あなたの場合、ボタンは UserControl のネームスコープにあるため、 Window.FindName() はそれを見つけられません。ツリーを下位レベルのスコープに自動的に検索することはありません

これは良いことです。「ウィンドウ」は、使用している UserControl の内部の詳細について何も知らない、または知りたくないはずです。UserControl 内にプロパティが必要な場合は、UserControl レベルで公開する必要があります。コントロールに独自の子を管理させます。

于 2009-11-19T16:27:39.110 に答える