在两个用户控件和主窗体之间传递对象

2023-12-06

因此,我有一个用作导航栏的主窗体和两个显示一些控件的用户控件。
In UserControlsA我有一些字段需要填写。使用这些数据,我创建了一个包含一些信息的对象。我需要将该对象传递给UserControlsB所以我可以在那里显示一些数据。

我的想法是创建该对象的三个实例,其中一个位于UserControlsA获取对象所需的信息,在主窗体中获取对象的“副本”UserControlsA,以及其中一UserControlsB可以从主窗体中获取信息。

然而,这似乎是多余的,甚至不起作用。这是一些代码:

主要形式:

public partial class main : Form
{
    public Object object { get; set; }
    public UCA uca;
    public UCB ucb;

    public Form1()
    {
        InitializeComponent();

        uca = new UCA();
        ucb = new UCB();

        panel2.Controls.Add(uca);
        panel2.Controls.Add(ucb);

        ucb.Visible = false;
        uca.Visible = true;

    }

    private void button1_Click(object sender, EventArgs e)
    {
        ucb.Visible = false;
        uca.Visible = true;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        ucb.Visible = true;
        uca.Visible = false;
    }
}

用户控件A:

public partial class UCA : UserControl
{
    public Object object { get; set; }
    
    public UCA()
    {
        InitializeComponent();
    }

    private void bUsage_Click(object sender, EventArgs e)
    {
        //Data is provided
        object = new Object(data);

        //I use var parent to try and access the object from the main form.
        var parent = Parent as Form1;
        object = parent.object;
    }
 }

        

用户控制B:

public partial class UCB : UserControl
{
    public Object object { get; set; }

    public UCB()
    {
        InitializeComponent();
    }

    public void updateData()
    {
        //I try to assign the object from the main form to this form's object.
        var parent = Parent as Form1;
        object = parent.object;
    }
}

使用 var Parent 不起作用。我能做些什么?


几个使用的例子INotifyPropertyChanged使用标准公共事件的接口和实现。

相关文档:
Windows 窗体数据绑定
Windows 窗体数据绑定中的更改通知
数据绑定相关接口

Using INotifyPropertyChanged:
UserControl 公开了一个公共属性(此处名为CustomDataObject, 简单的string输入第一个示例,object在第二。当然它可以是另一种类型)。
该物业的装饰有Bindable属性。这BindingDirection这里还有一个意图描述,没有附加模板。
添加了另外两个标准属性:

  • 默认值定义属性的默认值(创建控件时分配给属性的值)。代码生成器使用它来确定当前值是否应该序列化:如果它与属性设置的值匹配,则不会序列化。
    PropertyGrid 还使用它以粗体显示非默认值选择或分配。
  • 设计师序列化可见性指定属性应如何在设计时序列化。这里,设置为DesignerSerializationVisibility.Visible,表示该属性应该被序列化。

The INotifyPropertyChanged接口可以被视为一种简化的方法,使用相同的事件处理程序将属性绑定添加到多个属性,以通知值的更改。
接口的默认实现只需要一个公共事件类型属性更改事件处理程序被添加到类中。
当属性值更改时,设置器仅调用事件。执行此操作的方法略有不同;在这里我用的是OnPropertyChanged()方法使用来电者姓名归因于acquire调用它的属性的名称。它在 WinForms 和 WPF 中相当常见。


UCA用户控制:
UserControl(参见视觉示例)有两个可以更改绑定的按钮CustomDataObject适当的价值。他们的Click动作由ButtonsAction_Click.

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Forms;

public partial class UCA : UserControl, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string m_DataObject = string.Empty;

    public UCA() => InitializeComponent();

    [Bindable(true, BindingDirection.TwoWay), DefaultValue("")]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public string CustomDataObject {
        get => m_DataObject;
        set {
            if (m_DataObject != value){
                m_DataObject = value;
                OnPropertyChanged();
            }
        }
    }

    private void OnPropertyChanged([CallerMemberName] string propertyName = "") =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

    private void ButtonsAction_Click(object sender, EventArgs e)
    {
        var btn = sender as Button;
        CustomDataObject = (btn == SomeButton) ? txtInput1.Text : txtInput2.Text;
    }
}

UCB 用户控制:
这个另一个 UserControl 是receiver。它只是暴露了一个公共属性(ReceiverDataObject)将绑定到CustomDataObjectUCA 的财产。

The ReceiverDataObject属性也定义为[Bindable],与意图使其成为单向的。该属性不会引发任何事件。它接收一个值,将其存储在私有字段中并设置内部 UI 元素。

public partial class UCB : UserControl
{
    private string m_RecvDataObject = string.Empty;

    public UCB() => InitializeComponent();

    [Bindable(true, BindingDirection.OneWay)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public string ReceiverDataObject {
        get => m_RecvDataObject;
        set {
            m_RecvDataObject = value;
            txtPresenter.Text = m_RecvDataObject;
        }
    }
}

使用标准事件通知:
您还可以使用标准事件生成属性更改通知。
不同之处在于,每个属性都需要一个事件来通知更改。
如果您已经为此使用了事件委托,那么它可能是一个不错的选择,因为需要添加的内容很少:只需调用在属性设置器中引发事件的受保护方法即可。

在这里,我使用常见的 .Net 事件处理,使用事件处理器列表由底层 Component 类定义并由其公开Events属性,以添加删除事件订阅。
通常会调用与事件同名的受保护方法来引发事件,但On prefix.
Here, CustomDataObjectChanged活动 =>OnCustomDataObjectChanged() method.
您可以在所有标准控件中看到这种模式。

▶ The CustomDataObjectChanged分配给事件的名称不是一个选择:该事件必须与属性和属性具有相同的名称Changed suffix.
这就是模式,遵循它就足够了。

UCA用户控制:

public partial class UCA : UserControl
{
    private static readonly object Event_CustomDataObjectChanged = new object();
    private object m_DataObject = null;

    public UCButtonActions() => InitializeComponent();

    [Bindable(BindableSupport.Yes, BindingDirection.TwoWay), DefaultValue(null)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public object CustomDataObject {
        get => m_DataObject;
        set {
            if (m_DataObject != value){
                m_DataObject = value;
                OnCustomDataObjectChanged(EventArgs.Empty);
            }
        }
    }

    public event EventHandler CustomDataObjectChanged {
        add {
            Events.AddHandler(Event_CustomDataObjectChanged, value);
        }
        remove {
            Events.RemoveHandler(Event_CustomDataObjectChanged, value);
        }
    }

    protected virtual void OnCustomDataObjectChanged(EventArgs e)
    {
        if (Events[Event_CustomDataObjectChanged] is EventHandler evth) evth(this, e);
    }
}  

UCB 用户控制:
第二个 UserControl 不变。这只是接收器。


Form 类(或用作 Handler 的另一个类):

在表单构造函数或表单初始化后调用的任何其他方法中,使用数据绑定UCB 属性来链接两个 UserControl 的属性:

public SomeForm()
{
    InitializeComponent();
    ucb1.DataBindings.Add("ReceiverDataObject", uca1, "CustomDataObject", 
        false, DataSourceUpdateMode.OnPropertyChanged);
}

您还可以使用 BindingSource 进行调解:

BindingSource ucsSource = null;

public SomeForm()
{
    InitializeComponent();
    ucsSource = new BindingSource(uca1, null);
    ucb1.DataBindings.Add("ReceiverDataObject", ucsSource, "CustomDataObject", 
        false, DataSourceUpdateMode.OnPropertyChanged);
}

示例功能:

UserControls TwoWay DataBinding

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

在两个用户控件和主窗体之间传递对象 的相关文章

  • C++ 中的软(不是:弱)引用 - 这可能吗?有实施吗?

    在 C 中我正在使用boost shared ptr and boost weak ptr自动删除不再需要的对象 我知道这些与引用计数一起工作 在 Java 中 内存由垃圾收集器管理 它将内置对象引用视为strong WeakReferen
  • 将处理后的图形绘制到另一个图形中

    我想将一个经过处理的图形绘制到另一个图形中 I have two graphics var gHead Graphics FromImage h var gBackground Graphics FromImage b Transform
  • 赋值运算符和复制构造函数有什么区别?

    我不明白C 中赋值构造函数和复制构造函数之间的区别 是这样的 class A public A cout lt lt A A lt lt endl The copy constructor A a b The assignment cons
  • Mono 无法保存用户设置

    我在 Mono Ubuntu 上保存用户设置时遇到问题 这是代码示例 private void Form1 Load object sender EventArgs e string savedText Properties Setting
  • std::map 和二叉搜索树

    我读过 std map 是使用二叉搜索树数据结构实现的 BST 是一种顺序数据结构 类似于数组中的元素 它将元素存储在 BST 节点中并按其顺序维护元素 例如如果元素小于节点 则将其存储在节点的左侧 如果元素大于节点 则将其存储在节点的右侧
  • 调试内存不足异常

    在修复我制作的小型 ASP NET C Web 应用程序的错误时 我遇到了 OutOfMemoryException 没有关于在哪里查看的提示 因为这是一个编译时错误 如何诊断此异常 我假设这正是内存分析发挥作用的地方 有小费吗 Thank
  • 转到 C# WPF 中的第一页

    我正在 WPF 中使用导航服务 为了导航到页面 我使用 this NavigationService Navigate new MyPage 为了返回我使用 this NavigationService GoBack 但是如何在不使用的情况
  • Xamarin Android:获取内存中的所有进程

    有没有办法读取所有进程 而不仅仅是正在运行的进程 如果我对 Android 的理解正确的话 一次只有一个进程在运行 其他所有进程都被冻结 后台进程被忽略 您可以使用以下代码片段获取当前正在运行的所有 Android 应用程序进程 Activ
  • 通过不同 DLL 或 EXE 中的指针或引用访问 STL 对象时发生访问冲突

    我在使用旧版 VC6 时遇到以下问题 我只是无法切换到现代编译器 因为我正在处理遗留代码库 http support microsoft com kb 172396 http support microsoft com kb 172396
  • 用于从字符串安全转换的辅助函数

    回到 VB6 我编写了一些函数 让我在编码时无需关心字符串的 null 和 数字的 null 和 0 等之间的区别 编码时 没有什么比添加特殊情况更能降低我的工作效率了用于处理可能导致一些不相关错误的数据的代码 9999 10000 如果我
  • C# using 语句、SQL 和 SqlConnection

    使用 using 语句 C SQL 可以吗 private static void CreateCommand string queryString string connectionString using SqlConnection c
  • Silverlight Datagrid:在对列进行排序时突出显示整个列

    我的 Silverlight 应用程序中有一个 DataGrid 我想在对该列进行排序时突出显示整个列 它在概念上与上一个问题类似 Silverlight DataGrid 突出显示整列 https stackoverflow com qu
  • 过度使用委托对性能来说是一个坏主意吗? [复制]

    这个问题在这里已经有答案了 考虑以下代码 if IsDebuggingEnabled instance Log GetDetailedDebugInfo GetDetailedDebugInfo 可能是一个昂贵的方法 因此我们只想在调试模式
  • 以编程方式使用自定义元素创建网格

    我正在尝试以编程方式创建一个网格 并将自定义控件作为子项附加到网格中 作为 2x2 矩阵中的第 0 行第 0 列 为了让事情变得更棘手 我使用了 MVVM 设计模式 下面是一些代码可以帮助大家理解这个想法 应用程序 xaml cs base
  • 热重载时调用方法

    我正在使用 Visual Studio 2022 和 C 制作游戏 我想知道当您热重新加载应用程序 当它正在运行时 时是否可以触发一些代码 我基本上有 2 个名为 UnloadLevel 和 LoadLevel 的方法 我想在热重载时执行它
  • 在基类集合上调用派生方法

    我有一个名为 A 的抽象类 以及实现 A 的其他类 B C D E 我的派生类持有不同类型的值 我还有一个 A 对象的列表 abstract class A class B class A public int val get privat
  • boost::program_options:带有固定和可变标记的参数?

    是否可以在 boost program options 中使用此类参数 program p1 123 p2 234 p3 345 p12 678 即 是否可以使用第一个标记指定参数名称 例如 p 后跟一个数字 是动态的吗 我想避免这种情况
  • 如何确定母版页中正在显示哪个子页?

    我正在母版页上编写代码 我需要知道正在显示哪个子 内容 页面 我怎样才能以编程方式做到这一点 我用这个 string pageName this ContentPlaceHolder1 Page GetType FullName 它以 AS
  • 如何使用 std::array 模拟 C 数组初始化“int arr[] = { e1, e2, e3, ... }”行为?

    注意 这个问题是关于不必指定元素数量并且仍然允许直接初始化嵌套类型 这个问题 https stackoverflow com questions 6111565 now that we have stdarray what uses are
  • 如何创建向后兼容 Windows 7 的缩放和尺寸更改每显示器 DPI 感知应用程序?

    我是 WPF 和 DPI 感知 API 的新手 正在编写一个在 Windows 7 8 1 和 10 中运行的应用程序 我使用具有不同每个显示器 DPI 设置的多个显示器 并且有兴趣将我的应用程序制作为跨桌面配置尽可能兼容 我已经知道可以将

随机推荐

  • jquery 在回调内部使用 this 访问对象上下文

    让我们假设我定义了以下对象 var myObj function this hello Hello myObj prototype sayHello function var persons Jim Joe Doe John each pe
  • PHP 检测 SQL 注入尝试

    我的代码已经安全了 在 SQL 查询中使用参数 但是 我想检测是否有人attempts将某些内容注入到提交表单中 我找到了 Snort 但我需要 PHP 脚本级别的东西 而不是整个网络 这是一个包含学生个人信息的网站 因此 我们将警告 甚至
  • jQuery 淡入淡出 div 在设定的时间间隔内

    我想淡出集合中的第一个 div 然后淡入下一个 div 淡入淡出将在设定的时间触发 集合中的项目数为 1 到 n 这是 html 的示例 div class contentPanel div class content div style
  • 填补 OpenCV 中的漏洞[重复]

    这个问题在这里已经有答案了 我有一个从边缘检测模块中提取的边缘图OpenCV 精明的边缘检测 我想做的是填补边缘图中的漏洞 我在用C and OpenCV图书馆 在OpenCV中有一个cvFloodFill 函数 它将用种子填充孔 以及开始
  • 带有 ASP.Net 的新 Google Recaptcha

    我正在尝试获取新的谷歌验证码在我的 ASP NET 项目中工作 我在使其成为新项目 我不是机器人 时遇到问题 我在那里有旧的 在对developers google com网站进行了大量研究之后 一切看起来都一样 他们甚至向我指出了相同的d
  • Binding 与 x:Bind、使用 StaticResource 作为默认值以及它们在 DataContext 中的差异

    我花了大半天的时间试图制作ItemTemplate of a ListView with a UserControl可通过以下方式配置DependencyProperty上说UserControl 我遇到了关于这两种不同的一些奇怪的不一致之
  • Google+ android API PlusClient writeMoment 不执行任何操作

    为了在 Android 应用程序中实现社交功能 我尝试使用 PlusClient 类的 writeMoment 方法 但没有任何反应 我能够与 PlusClient 成功连接 并使用我的应用程序编写深层链接帖子 这是我打开 Google 连
  • 查找内存最后被释放的位置?

    非常一般 当发生访问冲突时 是否有一种简单的方法可以判断哪一行代码最后释放了内存块 不太一般 我对探查器的理解是它们会覆盖分配和释放过程 如果这是真的 他们是否会碰巧存储最后释放一段内存的代码行 以便当它稍后因访问冲突而崩溃时 您知道最后释
  • 无法加载默认凭据? (Node.js Google 计算引擎教程)

    情况 我按照这个教程 https cloud google com nodejs tutorials bookshelf on compute engine 一切正常 直到我这样做npm start并转到 http 本地主机 8080 我在
  • UITextField 的初始 iPhone 虚拟键盘显示速度很慢。是否需要这种破解?

    我有一个带有 UITextField 的应用程序 等等 当用户第一次点击文本字段时 在虚拟键盘出现之前有明显的延迟 在 3GS 上 延迟不太明显 但在较旧的 iPhone 上 延迟可能约为 1 秒 之后键盘总是立即弹出 延迟只是应用程序启动
  • 当图像接近边缘时,9 块阴影消失

    我正在使用 9 patch 为盒子生成阴影 如果图像宽度为 280dp 距框边缘 20dp 我会得到很好的阴影 315 度 但是 如果我让图像接触框边缘 右边缘的阴影几乎消失 这是我的布局
  • 需要根据 T-SQL 中准入日期列计算出的第一个“3 个月”,为列中的每个值添加 3 个月

    我有 14K 记录表 如下所示 与一个特定 client id 1002 相关的数据示例 我的日期格式是 mm dd yyyy 月份在前 ClientsEpisodes client id adm date disch date 1002
  • Android Fragment 生命周期问题(onActivityResult 上的 NullPointerException)

    我遇到一个问题 我找不到任何解释 我有一个使用 TabManager 显示片段的 FragmentActivity 如下所示 public class WorkOrderFormTabFragmentActivity extends Fra
  • django 更改默认运行服务器端口

    我想设置默认端口manage py runserver侦听无关的指定内容config ini 有没有比解析更简单的修复方法sys argv inside manage py并插入配置的端口 目标是跑 manage py runserver不
  • Wamp 服务器:更改 apache 的 httpd.conf?

    我正在尝试解决我的错误 我无法从服务器连接到我的 Android 应用程序 所有来源都将我引向以下教程作为解决方案 我已成功完成本教程中的所有步骤 除了 编辑Wamp服务器的httpd conf文件 IE 该教程说明了以下内容 4 在htt
  • 如何杀死 goroutine? [复制]

    这个问题在这里已经有答案了 我想知道如何杀死 停止 goroutine 所有示例都基于通道和选择 这似乎只有在 goroutine 包含一些可以在通道上监听的重复任务时才有效 有没有办法在下面的 goroutine 返回之前停止它 pack
  • 使用认知登录而不是证书来验证和订阅 aws IoT MQTT 主题?

    我是 AWS 的新手 我正在尝试弄清楚我的用例是否可行 我想创建一个移动应用程序 用户可以登录 电子邮件 facebook google 等 然后订阅 aws IoT 上的一些 MQTT 主题 以接收园艺系统的实时传感器数据 AWS 上有很
  • 使用循环提取一系列整数

    我有一些数据想要提取整数出现的频率 这是一些示例数据 df lt read table header T text A B C D 1 1 5 3 1 2 1 2 3 2 3 2 3 5 3 4 1 4 5 3 5 3 1 4 2 6 5
  • PostgreSQL 逻辑复制在 CREATE SUBSCRIPTION 上挂起

    我在 PostgreSQL 逻辑复制版本 15 上遇到问题 我也在 v10 和 v12 上进行了测试 但遇到了同样的问题 它需要复制来进行测试 因此源数据库和目标数据库位于同一服务器上 在我设置的配置文件中 postgresql conf
  • 在两个用户控件和主窗体之间传递对象

    因此 我有一个用作导航栏的主窗体和两个显示一些控件的用户控件 In UserControlsA我有一些字段需要填写 使用这些数据 我创建了一个包含一些信息的对象 我需要将该对象传递给UserControlsB所以我可以在那里显示一些数据 我