为何无法在MainWindow内部类中通过名称访问WPF元素?
为什么WPF内部类无法直接通过名称访问界面元素?
核心原因
WPF编译XAML时,会自动生成一个名为MainWindow.g.cs的部分类,把你在XAML里用Name="StackPanel1"定义的元素,生成为MainWindow类的私有字段。
私有成员的访问规则是:只有定义它的类(这里就是MainWindow)内部的成员能直接访问。你的MyClass是MainWindow的嵌套类,但它本质上是独立的类,没有权限直接访问MainWindow的私有字段——这和按钮的Click事件处理方法不一样:Add_Elements_Directly_Click是MainWindow的成员方法,属于MainWindow内部作用域,所以能直接用StackPanel1。
你的代码验证
你现在通过把StackPanel1作为参数传递给MyClass.AddNewListBoxes方法的写法是完全正确的,既符合C#的访问权限规则,也遵循了封装原则——让MyClass只关注添加ListBox的逻辑,不需要依赖MainWindow的界面元素细节。
补充说明
如果非要让嵌套类直接访问,你可以把XAML里的Name改成x:FieldModifier="internal",让StackPanel1变成内部字段,这样同一程序集里的嵌套类就能访问,但这种做法会破坏封装,不推荐使用。
你的XAML代码
<Window x:Class="WpfApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <!-- Scrollviewer contain ListBoxes --> <ScrollViewer Margin="20,84,20,175" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Hidden"> <StackPanel Name="StackPanel1" Orientation="Horizontal" Height="150"> <ListBox d:ItemsSource="{d:SampleData ItemCount=5}" Height="150" Width="120" HorizontalAlignment="Left"/> <ListBox d:ItemsSource="{d:SampleData ItemCount=5}" Height="150" Width="120" HorizontalAlignment="Left"/> <ListBox d:ItemsSource="{d:SampleData ItemCount=5}" Height="150" Width="120" HorizontalAlignment="Left"/> </StackPanel> </ScrollViewer> <!-- Button for adding ListBoxes--> <Button Name="Add_Elements_Directly" Content="Add Listboxes directly" Margin="30,284,545,100" Click="Add_Elements_Directly_Click" /> <Button Name="Add_Elements_ViaClass" Content="Add Listboxes via class" Margin="288,284,288,100" Click="Add_Elements_ViaClass_Click" /> </Grid> </Window>
你的C#代码
using System.ComponentModel; using System.Runtime.CompilerServices; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApp { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } class MyClass { public void AddNewListBoxes(StackPanel sp) { ListBox lb = new ListBox(); lb.Width = 120; lb.Height = 150; lb.HorizontalAlignment = System.Windows.HorizontalAlignment.Left; sp.Children.Add(lb); // StackPanel1.Children.Add(lb); // does not work! Why? } } private void Add_Elements_Directly_Click(object sender, RoutedEventArgs e) { ListBox lb = new ListBox(); lb.Width = 120; lb.Height = 150; lb.HorizontalAlignment = System.Windows.HorizontalAlignment.Left; StackPanel1.Children.Add(lb); } private void Add_Elements_ViaClass_Click(object sender, RoutedEventArgs e) { MyClass myClass = new MyClass(); StackPanel sp = StackPanel1; // StackPanel1 from xaml myClass.AddNewListBoxes(sp); } } }
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

