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

2024-01-03

对于 WinForms 程序,我已经习惯将控件的 Modifiers 属性标记为“私有”,以防止外部类和其他任何您能够看到和弄乱它们的东西。

由于 WPF 还很陌生,我在 WPF 中看不到明显的等效项,因此外部类无法看到我放到表单或另一个用户控件或其他控件上的控件。我确实注意到 x:FieldModifier = "Private" 的某些内容,但收到错误“x:FieldModifier = "Private" 对于 C# 语言无效”。

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


TL;DR

大多数时候您不需要在 WPF 中担心这个问题。然而:

  • 如果您使用以下方式命名 XAML 元素x:Name属性,那么你可以使用x:字段修改器属性来控制表示该元素的自动生成字段的可见性。该属性值是特定于语言和大小写的。
  • 如果您没有命名 XAML 元素,则不必费心使用x:字段修改器属性。

请继续阅读以获取更详细的解释。


显式命名和生成字段

如果您在 Visual Studio 中创建一个新的 WPF 应用程序项目,它将创建一个主窗口类,其 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 资源管理器,您会发现一个名为主窗口.g.cs:这个文件包含 IDE 从 XAML 生成的代码(它基本上相当于*.Designer.cs来自 WinForms 的文件)。

你的窗户有一个Grid其上,但请注意,它没有直接出现在代码中的任何位置主窗口。现在编辑您的 XAML 以给出Grid a name:

<Grid x:Name="_myGrid">

编译应用程序,然后打开主窗口.g.cs再次归档。您将看到添加了以下行:

internal System.Windows.Controls.Grid _myGrid;

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

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


仍然可以从代码访问无名 UI 元素(如果您有实例)

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

Grid grid = (Grid) this.Content;

this这里指的是主窗口类实例。

WinForms 在这方面与 WPF 有着完全相同的“问题”:即使没有显式命名的控件仍然可以通过代码访问。想象一下 WinFormsForm与单个Button对其进行控制。您可以像这样访问该按钮:

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

事实上该按钮有一个默认值修饰符“Private”的值并没有阻止代码访问它。


FieldModifier 属性控制生成的字段可见性

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

<Grid x:Name="_myGrid" x:FieldModifier="private">
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 WPF 中将控件标记为“私有”? 的相关文章

  • 如何查找boost运行时版本

    我正在编写一个使用 boost 的 C 库 在这个库中 我想包含有关用于编译我的库的二进制版本的 boost 版本的信息 我可以使用宏BOOST VERSION这很好 我还想确定哪个是 boost 的运行时版本 以便我可以与用于编译我的库的
  • 将数组从 C# 编组到 C++ 并返回:PInvokeStackImbalance

    我有一个 C 函数 我想从 C 访问它 问题是我不断收到 PInvokeStackImbalance 异常 但我不知道为什么 当检查异常被关闭时 一切都运行良好并且符合预期 我的 C 函数的签名是 extern C double solve
  • 线程安全的get(访问器方法)

    我目前正在使用以下代码对变量进行线程安全访问 int gnVariable void getVariableValue int pnValue acquireLock Acquires the protection mechanism pn
  • 带有复选框的 WPF ListBox:在选中之前选择复选框

    Problem 我有一个列表框 其中列表框是复选框 第一次单击时 复选框将被选中并选中 第二次单击时 仅设置复选框 人们可以使用箭头键重新选择不同的复选框 我的目标是 首先选择复选框 然后再检查 再次单击它 从而消除对箭头键的需要 Goal
  • c++11 中的 std::thread 问题

    我在尝试从标准模板库编译具有多线程的程序时遇到一些麻烦 当我尝试编译以下程序时 它返回一个晦涩的错误 include
  • C++ 克隆惯用语中协变返回类型的用处?

    通常的克隆习惯使用协变返回类型 struct Base virtual Base clone struct Derived public Base Derived clone 我读过一些内容 大意是协变返回类型是 C 后来添加的 较旧的编译
  • 使用经度和纬度查找给定距离内的所有附近客户

    我有一个包含客户经度和纬度的数据库 我有一个搜索表单 用户将在其中输入日志 纬度 距离下拉列表包含 50 英里 100 英里 当用户单击搜索时 我想编写一个 linq 查询从数据库中获取此距离半径内的所有客户 如何使用 C 和 linq 来
  • NHibernate 中具有不同类型答案的问题

    我正在尝试找到一个问卷问题的简洁解决方案 假设我有一个Questionnaire类有一个集合Answers e g public class Questionnaire public virtual ISet
  • 标准头文件中的 C 编译器错误 - 未定义的 C++ 定义

    我正在尝试编译 C 程序 但收到许多错误 这些错误是在标准 C 头文件 inttypes h stdio h stat h 等 中遇到的 错误的来源是以下未定义的常量 BEGIN DECLS END DECLS BEGIN NAMESPAC
  • 如何在 Xamarin.Mac 中执行终端命令并读入其输出

    我们正在编写一个 Xamarin Mac 应用程序 我们需要执行像 uptime 这样的命令 并将其输出读取到应用程序中进行解析 这可以做到吗 在 Swift 和 Objective C 中都有 NTask 但我似乎无法在 C 中找到任何示
  • 无论表单上的焦点控件如何,如何捕获 Keys.F1?

    我使用了 KeyDown 事件和一些简单的代码 例如if e KeyCode Keys F1 捕获在表单上按下 F1 但如果表单上有一些文本框 或者表单上有一些带有 Dock Fill 的电子表格 则上面的代码将毫无用处并且不执行任何操作
  • 我可以在C中直接比较int和size_t吗?

    我可以比较一个int and a size t像这样的变量 int i 1 size t y 2 if i y Do something 或者我必须输入其中之一 只要满足以下条件 它就是安全的int为零或正数 如果它是负数 并且size t
  • 选择要重写哪个基类的方法

    鉴于以下情况 class Observer public virtual void Observe Parameter p 0 template
  • 什么是多重重继承?

    我将以下称为 多重重新继承 直接继承一个类一次 并通过继承其一个或多个后代来间接继承一次或多次 通过继承一个类的两个或多个后代来间接继承一个类两次或多次 我想知道它是否存在以及如何明确访问嵌入的子对象 1 Professional C 2n
  • 组合框由于某种原因被链接

    我有以下代码来填充 3 个组合框 private void PopulateDDLs SqlConnection connection SqlCommand command SqlDataReader reader DataTable dt
  • 如何并排显示 4 个三角形图案

    我无法让 4 个不同的三角形图案并排出现 这是一个控制台应用程序 这正是我试图通过使用嵌套 for 循环来实现的目标
  • 当另一个进程使用 std::fstream 写入文件时从文件读取[重复]

    这个问题在这里已经有答案了 我需要从文件中逐行读取 它是由 std getline 完成的 另一个进程的问题是一直向其附加数据 然后我需要读取新行 例如 文件一开始包含10行 我的程序读取了10行 那么我的程序应该等待 过了一会儿 另一个进
  • 如果未返回,则在一段时间后终止线程

    我有一个线程从网络或串行端口获取一些数据 如果 5 秒内没有收到数据 则线程必须终止 或返回 false 换句话说 如果线程运行时间超过 5 秒 则必须停止 我用 C 编写 但任何 NET 语言都可以 有两种方法 1 封装超时 从网络或串行
  • 中继命令和无参数执行方法

    我目前正在学习 WPF 和 MVVM 我想我已经了解了大部分内容及其工作原理 但我在使用 RelayCommand 或 DelegateCommand 时遇到了一些我不明白的问题 我认为这与代表的工作方式有关 请注意 下面的代码目前仅处于测
  • 如何在Asp.Net Core中自定义开发者异常页面?

    这常见于ConfigureStartup cs 文件的方法具有如下所示的代码 if env IsDevelopment app UseDeveloperExceptionPage new DeveloperExceptionPageOpti

随机推荐