2009-11-19 15 views
5

Aşağıdaki örnek kodda, Window1.xaml ana penceresinin alt öğesi olan bir UserControl UserControldChild oluşturun. FindName() yöntemi neden aşağıdaki kodda "myButton" ifadesini bulamıyor?Neden Window.FindName(), x bir kullanıcı UserControl içindeki bir düğmenin adı? AKA NameScopes nasıl çalışır?

Bu, WPF XAML NameScopes ile ilgili olmak zorundadır, ancak NameScope'un nasıl çalıştığı konusunda henüz iyi bir açıklama bulamadım. Birisi beni aydınlatır mı? Aşağıda

//(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: Bu doğru cevap almaz durumda

//(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(); 
    } 
    } 
} 

, ben FindName kullanmaya bir alternatif bulundu() in the post here belgelenmiştir.

cevap

5

Haklısınız - bu XAML Adlandırma Adlarıyla ilgilidir.

Bu, Name related APIs section of the XAML Namescopes page numaralı belgede belgelenmiştir (biraz zayıf).

Temel olarak, bir FrameworkElement veya FrameworkContentElement öğeniz varsa, kendi ad alanını tanımlar. FindPame() adında bir adı bulunmayan bir adla çağırırsanız, WPF 'u numaralı dizgede arama yapar, böylece bir nameskop tanımlayan bir öğe bulana kadar o adkopta arar.

Sizin durumunuzda, Window'un namescope'sunda arama yapıyor (bu bir FrameworkContentElement, yani kendi kapsamını tanımlar). Sadece bu kapsamda tanımlanan öğeleri arar.

Sizin durumunuzda, bu düğme UserControl'ın nameskop'unda olsa da Window.FindName() bulamıyor. ağacında alt düzey kapsamlara otomatik olarak arama yapılmamaktadır.

Bu iyi bir şeydir - "Pencere" öğeniz, kullanmakta olduğu bir UserControl öğesinin iç detayları hakkında hiçbir şey bilmemeli veya bilmek istememelidir. UserControl içinde mülklere ihtiyacınız varsa, bunlar UserControl seviyesinde açık olmalıdır - kontrol kendi çocuklarını yönetsin.

+0

Açıklama için teşekkürler! FindName bu durumda iş için en iyi araç olmayacak gibi görünüyor, aka sen kolayca kapsama içinde arama yapamazsın. Görsel ağacındaki çocuk düğmesinin ismini burada ayrıntılı olarak özellile özümümden başka nasıl bulacağımı düşünebilir misiniz? http://stackoverflow.com/questions/636383/wpf-ways-to-find-controls/1759923#1759923 – CrimsonX

İlgili konular