如何在 WPF 中将控件标记为“私有"? [英] How do I mark a control as 'Private' in WPF?

查看:119
本文介绍了如何在 WPF 中将控件标记为“私有"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 WinForms 程序时,我已经习惯于将控件的 Modifiers 属性标记为私有",以防止外部类和其他任何您能够看到和弄乱它们的内容.

With WinForms programs I've become accustomed to marking the Modifiers property of a control as 'Private' to prevent external classes and whatever else have you from being able to see and mess with them.

使用 WPF 仍然非常绿色,我在 WPF 中看不到明显的等效项,它允许我使它这样外部类无法看到我放到窗体或另一个用户控件上的控件或其他控件.我确实注意到 x:FieldModifier = "Private" 但我收到错误x:FieldModifier = "Private" is not valid for the language C#".

Being still very green with WPF, I see no obvious equivalent in WPF that allows me to make it so external classes cannot see a control I drop onto a form or another user control or what not. I did notice something of x:FieldModifier = "Private" but I get the error "x:FieldModifier = "Private" is not valid for the language C#".

如何将控件标记为私有,使其无法被外部类对象查看或访问?

How do I mark a control as Private so it cannot be viewed or accessed by external class objects?

推荐答案

TL;DR

大多数情况下,您无需在 WPF 中担心这一点.但是:

Most of the time you don't need to worry about this in WPF. However:

  • 如果您使用 x:Name 属性命名 XAML 元素,那么您可以使用 x:FieldModifier 属性来控制自动-表示该元素的生成字段.此属性值特定于语言和案例.

  • If you name a XAML element using the x:Name attribute, then you can use the x:FieldModifier attribute to control the visibility of the auto-generated field representing that element. This attribute value is language- and case-specific.

如果您没有为 XAML 元素命名,则不要使用 x:FieldModifier 属性.

If you don't name a XAML element, then don't bother using the x:FieldModifier attribute.

继续阅读以获得更详细的解释.

Read on for a more detailed explanation.

<小时>

显式命名和生成的字段

如果您在 Visual Studio 中创建一个新的 WPF 应用程序项目,它将创建一个 MainWindow 类,其 XAML 如下所示:


Explicit naming and generated fields

If you create a new WPF application project in Visual Studio, it will create a MainWindow class, the XAML for which looks something like this:

<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>

如果您查看此窗口的代码隐藏类,它将如下所示:

If you look at the code-behind class for this window, it will look like this:

// Several using statements...

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

注意使用 partial 关键字将其表示为分部类.如果您使用 Windows 资源管理器导航到项目的 obj\Debug 文件夹,您将找到一个名为 MainWindow.g.cs 的文件:该文件包含由XAML 中的 IDE(它基本上相当于 WinForms 中的 *.Designer.cs 文件).

Note the use of the partial keyword to denote this as a partial class. If you navigate to the project's obj\Debug folder using Windows Explorer, you will find a file called MainWindow.g.cs: it is this file that contains the code generated by the IDE from your XAML (it is basically the equivalent of the *.Designer.cs file from WinForms).

您的窗口上有一个网格,但请注意,它不会直接出现在 MainWindow 的代码中的任何位置.现在编辑您的 XAML,为 Grid 命名:

Your window has a Grid on it, but note that it is not surfaced directly anywhere in the code for MainWindow. Now edit your XAML to give the Grid a name:

<Grid x:Name="_myGrid">

编译应用程序,然后再次打开 MainWindow.g.cs 文件.您将看到添加了以下行:

Compile the application, and open the MainWindow.g.cs file again. You will see that the following line has been added:

internal System.Windows.Controls.Grid _myGrid;

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

Setting the x:Name property of the element in the XAML has caused the code generator to add a field with that name. The field is marked as internal which means it is accessible to all types in your project, but not to any other projects that reference your project.

所以基本上,如果您没有使用 x:Name 属性显式命名 XAML 中的元素,代码生成器将不会为代码隐藏类中的元素创建命名字段,并且您的元素实际上是 private(这意味着类本身也不能直接访问该元素).

So basically, if you do not explicitly name an element in the XAML using the x:Name attribute, the code generator will not create a named field for the element in the code-behind class, and your element will effectively be private (this means that the class itself cannot access the element directly either).

然而你应该记住,仅仅因为一个元素没有名字并不意味着它不能通过代码访问.您始终可以走"可视化树并以这种方式访问​​元素.例如,由于窗口的内容设置为单个 Grid 元素,您可以通过如下代码访问该网格:

You should bear in mind however that, just because an element does not have a name does not mean it cannot be accessed via code. You can always "walk" the visual tree and access elements that way. For example, because the window's content is set to a single Grid element, you can access that grid through code like so:

Grid grid = (Grid) this.Content;

this 指的是 MainWindow 类实例.

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

WinForms has exactly the same "problem" as WPF in this regard: even controls that are not explicitly named can still be accessed through code. Imagine a WinForms Form with a single Button control on it. You can access that button like so:

Button button = (Button) this.Controls[0];

按钮具有默认的修饰符值Private"这一事实并没有阻止代码访问它.

The fact that the button had a default Modifiers value of "Private" did not stop the code from being able to access it.

回到 WPF,特别是当您使用模型-视图-视图模型 (MVVM) 模式时,您很少需要在 XAML 中显式命名您的元素,因此默认行为就可以了.但是,如果您确实发现需要命名 XAML 元素,并且希望隐藏"这些元素,则可以使用 x:FieldModifier 属性将元素的可见性设置为 private 而不是默认的 internal.用于属性的值取决于语言且区分大小写,例如.对于 C#:

Coming back to WPF, particularly if you're using the Model-View-ViewModel (MVVM) pattern, you will rarely need to explicitly name your elements in the XAML, hence the default behaviour will be fine. However, if you do find that you need to name your XAML elements, and you wish to "hide" these elements, then you can use the x:FieldModifier attribute to set the visibility of an element to private instead of the default internal. The value used for the attribute is language-dependent and case-sensitive, eg. for C#:

<Grid x:Name="_myGrid" x:FieldModifier="private">

这篇关于如何在 WPF 中将控件标记为“私有"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆