在WPF中如何将一个控件标记为“私有”?

6

在WinForms程序中,我已经习惯了将控件的Modifiers属性标记为“Private”,以防止外部类或其他对象查看和干扰。

对于WPF,作为一个新手,我没有找到明显的等价方法来防止外部类或其他对象查看我放置在窗体或其他用户控件上的控件。我注意到了x:FieldModifier = "Private"这个东西,但是我得到了错误提示:“x:FieldModifier = "Private"不适用于C#语言。”

如何将控件标记为Private,以便外部类对象无法查看或访问?


1
使用NonPublic代替Private。请参阅MSDN上的x:FieldModifier Directive - Wai Ha Lee
1
当然 -.-; 谢谢... - Will
阅读您提供的链接帮助我理解,NotPublic 在 C# 中的等效项是 Internal,但仍不是我要寻找的东西...也许这在 WPF 中是不可能的?这没有意义,会很烦人... - Will
是的,看起来 internal 是唯一的选择... - Wai Ha Lee
1
嗯——不用了,这不是什么重大问题,我也不想采取那种方式来处理它…… - Will
显示剩余3条评论
1个回答

22

简而言之

在大多数情况下,在WPF中您不需要担心这个问题。但是:

  • 如果您使用x:Name属性对XAML元素进行命名,则可以使用x:FieldModifier属性来控制表示该元素的自动生成字段的可见性。此属性值与语言和大小写有关。
  • 如果您没有给XAML元素命名,则不必使用x:FieldModifier属性。

阅读以下详细说明。


显式命名和生成字段

如果在Visual Studio中创建一个新的WPF应用程序项目,它会创建一个MainWindow类,其XAML代码看起来像这样:

<Window x:Class="StackOverflow.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid>

    </Grid>
</Window>

如果你查看这个窗口的后台代码类,它会像这样:

// Several using statements...

namespace StackOverflow
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

请注意使用partial关键字将其标记为部分类。如果您使用Windows Explorer导航到项目的obj\Debug文件夹,您将找到一个名为MainWindow.g.cs的文件:这个文件包含了IDE从您的XAML生成的代码(它基本上相当于来自WinForms的*.Designer.cs文件)。

您的窗口上有一个Grid,但请注意在MainWindow的任何代码中都没有直接暴露出来。现在编辑您的XAML以给Grid命名:

<Grid x:Name="_myGrid">

编译应用程序,再次打开MainWindow.g.cs文件。您会看到以下行已经添加:

internal System.Windows.Controls.Grid _myGrid;

在XAML中设置元素的x:Name属性会导致代码生成器添加一个具有该名称的字段。该字段标记为internal,这意味着它对项目中的所有类型都是可访问的,但对引用您项目的任何其他项目都不可访问。

因此,基本上,如果您不使用x:Name属性显式命名XAML中的元素,则代码生成器将不会在代码后台类中创建一个命名字段,并且您的元素将有效地成为private(这意味着该类本身也无法直接访问元素)。


没有名称的UI元素仍然可以从代码中访问(如果您有一个实例)

没有名称的元素仍然可以通过代码访问,通过“遍历”Window实例的可视树。例如,因为窗口的内容设置为单个Grid元素,您可以通过以下方式通过代码访问该网格:

Grid grid = (Grid) this.Content;

this在这里指的是MainWindow类实例。

WinForms在这方面与WPF完全相同:即使没有明确命名控件,这些控件仍然可以通过代码访问。想象一个WinForms Form,上面有一个单独的Button控件。您可以像这样访问该按钮:

Button button = (Button) this.Controls[0];
<Grid x:Name="_myGrid" x:FieldModifier="private">

2
很好的综合回答。如果将 x:FieldModifier="private" 移到开头,那就更好了,因为这才是实际的答案。 - Metalogic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接