2010-11-23 5 views
11

OKので、ここで(任意の間違いを指摘して自由に感じる)擬似C#コードとして記述され、私の問題のためにいくつかのコンテキストである:(。あなたがスタックトレースに直接ジャンプし、後でコンテキストを読むことができます)親オブジェクトで通知イベントを発生させたときに、Windows Formsのデータバインディングでネストされたブール値のdataboundプロパティを設定するのはなぜですか?

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)); 
    } 
} 

これらのクラスに記載されているすべてのプロパティは、Visual Studio 2008 Windowsフォームデザイナ、SomeFormまたはSomeControlクラスでデータバインドされています。 (ComplexObject.BoolPropは両方ともデータバインドされています)。文脈についてさらに疑問を投げかけてください。

問題:私はいくつかを作るViewModelClassクラスの通知(の束)が、falseからComplexObject.BoolPropを設定し、膝ジャーク反応のいくつかの種類がスタックトレースのようなものを使用して、そこにある:

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 

なぜプログラムはSomeBoolfalseに設定しますか?そして私はそれをどうやって防ぐことができますか?

+0

ViewModelClassクラスの通知はどのように行われますか?たとえば、コードから、またはユーザーインターフェイスのアクションの結果として、 –

+0

あなたは "SomeBoolをfalseに設定する"と書いています。 BoolPropをfalseに設定する必要がありますか? –

答えて

0

ViewModelClassSomeFormViewModelおよびSomeControlViewModelにリファクタリングし、それらをそれぞれのクラスに結合させた。

これを実行するだけで問題が解決しました。

私はスタックトレースをよく理解したいと思いますが、問題の要点はそれぞれ、オブジェクトに加えられた変更について独自の情報を保持しているということです同じオブジェクトに変更されても、もう何が起こっているのか分からなかった。

4

スタックオーバーフローに関する私の最初の質問は、あなたのような予期しない値を含むWindows Formsアプリケーションのフィールドに関するものでした。解決策は、フォームのGUI要素を設定するためにフォームロードイベントが発生するまで待つことでした。

フォームロードイベントのハンドラに入るまで、(newで構築することを含む)と他のGUI要素の設定を延期します。

HOWTO:

は、Visual Studioでフォームのロードハンドラを追加します。

  1. オープングラフィカルビューでフォーム(例えば、ソリューションエクスプローラでSomeForm.csをダブルクリックします)

  2. フォーム内で、コントロールやその他のGUI要素(タイトルバーなど)の外側をダブルクリックします。これにより、SomeForm_Loadという名前の関数のスケルトンコードが追加され、this.Load += new System.EventHandler(this.SomeForm_Load);という行にSomeForm.Designer.csが追加されます。

SomeForm_Loadにセットアップコードを移動し

_modelの宣言から

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

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

削除 "= new ViewModelClassを"。

+0

返信いただきありがとうございます。私はそれを試してみることができます(これは2日以上しかないので、気をつけてください) –

+0

* sigh *は私の問題を解決しません。問題は初期化時ではなく、その後のある時点で、Windowsフォームのデータバインディングがオブジェクトプロパティの設定に使用されなくなります。再度、答えをくれてありがとう。 –

+0

@jhominal:1)BoolPropの最初の設定をfalseにキャッチするコードをインストルメントしましたか? (質問のスタックダンプ用)2)私は問題を再現できるはずだと思いますか? –

0

tabcontrolのタブを変更すると、すべてのデータバインドされたブール値が「false」にリセットされるという同じ問題がありました。すべての非ブール値は正常でした。スタックトレースはOPと全く同じでした。

Peterが提案したように、ViewModelの設定をForm_Loadに移動しようとしましたが、運はありません。最終的にデータソースを作成し、すべてのコントロールプロパティでデータバインドを設定することで、コードからすべてのデータバインディングをUIに設定するようになりました。

関連する問題