简体   繁体   English

为什么Windows窗体数据绑定想要在父对象上引发通知事件时设置我的嵌套布尔数据绑定属性?

[英]Why does Windows Forms databinding want to set my nested boolean databound property when I raise a notification event on the parent object?

OK, so here is some context for my problem, written as pseudo-C# code (feel free to point out any mistake): (You can jump directly to the stacktrace and read the context later.) 好的,所以这里是我的问题的一些上下文,写成伪C#代码(随意指出任何错误):(你可以直接跳转到堆栈跟踪并稍后阅读上下文。)

public class SomeForm {
    private _model = new ViewModelClass
    public void new() {
        // Normal Winforms init omitted
        ViewModelClassBindingSource.DataSource = _model;
        SomeControl1.SetModel(_model);
    }
}
public class SomeControl {
    private _model = new ViewModelClass

    internal void SetModel(ViewModelClass model) {
        _model = model;
        ViewModelClassBindingSource.DataSource = model;
        ViewModelClassBindingSource.ResetBindings(true);
    }
}

public class ComplexObject : IPropertyChanging, IPropertyChanged {
    public property bool BoolProp {get; set;}
}

public class ViewModelClass : IPropertyChanged {
    property IList<ComplexObject> ComplexObjects {get;}

    property ComplexObject SelectedComplexObject {get; set;}

    property Object SomethingNotNecessarilyRelated {get; set;}

    private void NotifyPropertyChanged(string propName) {
        PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }
}

All of the mentioned properties in these classes are databound in the Visual Studio 2008 Windows Forms designer, in the SomeForm or in the SomeControl classes. 这些类中提到的所有属性都是在Visual Studio 2008 Windows窗体设计器, SomeFormSomeControl类中进行数据绑定。 ( ComplexObject.BoolProp is databound in both). ComplexObject.BoolProp在两者中都是数据绑定的)。 Don't hesitate to ask more questions about the context. 不要犹豫,就上下文提出更多问题。

The problem: When I make some (bunch of) notifications in the ViewModelClass class, there is some kind of knee-jerk reaction that sets ComplexObject.BoolProp to false , using that kind of stack trace: 问题:当我在ViewModelClass类中发出一些(一堆)通知时,会出现某种类型的下意识反应,使用这种堆栈跟踪将ComplexObject.BoolProp设置为false

System.dll!System.ComponentModel.ReflectPropertyDescriptor.SetValue(object component = "Object Exposed in 'SelectedComplexObject'", object value = false) + 0x124 bytes 
System.Windows.Forms.dll!System.Windows.Forms.BindToObject.SetValue(object value) + 0x5d bytes  
System.Windows.Forms.dll!System.Windows.Forms.Binding.PullData(bool reformat, bool force) + 0x15a bytes 
System.Windows.Forms.dll!System.Windows.Forms.BindingManagerBase.PullData(out bool success = true) + 0x6e bytes 
System.Windows.Forms.dll!System.Windows.Forms.BindingSource.ParentCurrencyManager_CurrentItemChanged(object sender = {System.Windows.Forms.CurrencyManager}, System.EventArgs e) + 0x54 bytes   
[Native to Managed Transition]  
[Managed to Native Transition]  
System.Windows.Forms.dll!System.Windows.Forms.CurrencyManager.OnCurrentItemChanged(System.EventArgs e) + 0x17 bytes 
System.Windows.Forms.dll!System.Windows.Forms.CurrencyManager.List_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e) + 0x3bc bytes   
System.Windows.Forms.dll!System.Windows.Forms.BindingSource.OnListChanged(System.ComponentModel.ListChangedEventArgs e) + 0x7e bytes    
System.Windows.Forms.dll!System.Windows.Forms.BindingSource.InnerList_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e) + 0x2e bytes 
System.dll!System.ComponentModel.BindingList<System.__Canon>.OnListChanged(System.ComponentModel.ListChangedEventArgs e) + 0x17 bytes   
System.dll!System.ComponentModel.BindingList<MyCompany.ViewModelClass>.Child_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + 0x176 bytes 
[Native to Managed Transition]  
[Managed to Native Transition]  
MyCompany.Gui.exe!MyCompany.ViewModelClass.NotifyPropertyChanged(String propertyName = "SomethingNotNecessarilyRelated") Line 437 + 0x3c bytes  Basic

Why does the program want to set SomeBool to false ? 为什么程序想将SomeBool设置为false And how I can prevent that? 我怎么能防止这种情况?

My very first question on Stack Overflow was about a field in a Windows Forms application containing an unexpected value, like yours. 关于Stack Overflow的第一个问题是关于Windows Forms应用程序中包含意外值的字段,就像你的一样。 The solution was to wait until the form load event was fired to set up the GUI elements of the form. 解决方案是等到表单加载事件被触发以设置表单的GUI元素。

I would postpone setting up _model (including constructing it with new ) and other GUI elements until in the handler for the form load event. 我会推迟设置_model (包括用new构建它)和其他GUI元素,直到在表单加载事件的处理程序中。

HOWTO: 如何:

Add the form load handler in Visual Studio: 在Visual Studio中添加表单加载处理程序:

  1. Open the form in the graphical view (for example, double-click SomeForm.cs in Solution Explorer) 在图形视图中打开表单(例如,在解决方案资源管理器中双击SomeForm.cs

  2. Double click in the form, outside any controls or other GUI elements (for example, in the title bar). 双击表单,在任何控件或其他GUI元素之外(例如,在标题栏中)。 This will add skeleton code for a function named SomeForm_Load and the line this.Load += new System.EventHandler(this.SomeForm_Load); 这将为名为SomeForm_Load的函数添加框架代码,并添加this.Load += new System.EventHandler(this.SomeForm_Load); will be added the SomeForm.Designer.cs . 将添加SomeForm.Designer.cs

Move the setup code to SomeForm_Load : 将设置代码移动到SomeForm_Load

private void SomeForm_Load(object aSender, EventArgs anEvent)
{
    _model = new ViewModelClass;

    ViewModelClassBindingSource.DataSource = _model;
    SomeControl1.SetModel(_model);
}

Remove " = new ViewModelClass " from the declaration of _model . _model的声明中删除“ = new ViewModelClass ”。

I have refactored the single ViewModelClass into SomeFormViewModel and SomeControlViewModel , and binding them to their respective classes. 我已将单个ViewModelClass重构为SomeFormViewModelSomeControlViewModel ,并将它们绑定到各自的类。

Simply doing that has made the issue disappear. 简单地这样做就会使问题消失。

I would still like a better understanding of the stacktrace that I put, though - I conjecture that the gist of the problem is that each BindingSource maintains its own information of the changes made to the object - and as both of them made changes to the same object, they did not know what was happening anymore. 我仍然希望更好地理解我所放置的堆栈跟踪 - 我猜想问题的关键是每个BindingSource维护自己对对象所做更改的信息 - 并且因为它们都对它们进行了更改对象,他们不知道发生了什么事。

Had the same issue, where changing tab in a tabcontrol would reset all my databound boolean values to "false". 有同样的问题,在tabcontrol中更改选项卡会将我的所有数据绑定布尔值重置为“false”。 All non-boolean values were fine. 所有非布尔值都很好。 Stack trace showed exactly the same as OP. 堆栈跟踪显示与OP完全相同。

Tried moving around the setting of the viewmodel to Form_Load like Peter suggested, but no luck. 试图像Peter建议的那样将视图模型的设置移动到Form_Load,但没有运气。 Eventually gave up and moved all the databinding from code to setting it in the UI, by creating a data source and setting the databinding on all the control properties. 通过创建数据源并在所有控件属性上设置数据绑定,最终放弃并将所有数据绑定从代码移动到在UI中设置它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Windows forms 工具提示属性“ShowAlways”在父 object 被禁用时不起作用 - Windows forms ToolTip property “ShowAlways” not working when parent object is disabled 当我从控制台应用程序打开它时,为什么我的 Windows 窗体布局会发生变化? - Why does my Windows-Forms Layout change, when I am opening it from a Console-Application? 在.NET Windows窗体中处理对象的对象属性更改事件 - Handle an object's object property changed event in .NET Windows Forms 引发事件时.NET虚拟机会做什么? - What does the .NET Virtual Machine do when I raise an event? 当我捕获了子属性时,父对象超出了范围-它何时处理子属性? - Parent object goes out of scope when I have captured child property - when does it dispose the child property? Windows窗体数据绑定DisplayMember自定义类的子属性 - Windows Forms Databinding DisplayMember a Custom Class's Child Property 为什么GC在我引用它时会收集我的对象? - Why does GC collects my object when I have a reference to it? 我无法读取我刚刚在对象中设置的属性。 为什么? - I cannot read a property that I just set in my object. Why? Windows窗体数据绑定和可为空的类型 - Windows Forms databinding and nullable types 数据绑定-数据绑定控制 - Databinding - databound control
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM