3

Windows フォーム プロジェクトでMVVMパターンを使用してマスター/詳細シナリオを実装しようとしています (私は怒っています)。次のビュー モデルを検討してください。

public class MasterViewModel
{
    public BindingList<DetailViewModel> Details { get; set; }

    public DetailViewModel SelectedDetail
    {
        get
        {
            //
        }
        set
        {
            // raises SelectedDetailChanged
        }
    }
}

public class DetailViewModel
{
    public string SubProperty
    {
        get
        {
            // ...
        }
        set
        {
            // ... raises SubPropertyChanged
        }
    }
}

次のコード (および Windows フォーム データバインディングでサポートされているプロパティ パス) を使用して、DetailViewModel の SubProperty を TextBox にバインドしようとしています。

            MasterViewModel masterViewModel;
            TextBox textBox;
            // ...

            Binding binding = new Binding("Text", masterViewModel, "SelectedDetail.SubProperty");
            binding.FormattingEnabled = true;
            binding.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
            binding.ControlUpdateMode = ControlUpdateMode.OnPropertyChanged;

            textBox.DataBindings.Add(binding);

SelectedDetailがnullになるまで(WPFのように)問題なく動作します(私のロジックでは、SelectedDetail nullはマスタービューで何も選択されていないことを意味します)。SelectedDetail が null の場合、ArgumentNullException (パラメータ名: コンポーネント) が発生しました。

「親」プロパティ (ナビゲーション パス内) の null 可能性を処理する方法はありますか?

例外スタックトレースは次のとおりです。

   in System.ComponentModel.ReflectPropertyDescriptor.AddValueChanged(Object component, EventHandler handler)
   in System.Windows.Forms.BindToObject.CheckBinding()
   in System.Windows.Forms.BindToObject.SetBindingManagerBase(BindingManagerBase lManager)
   in System.Windows.Forms.Binding.SetListManager(BindingManagerBase bindingManagerBase)
   in System.Windows.Forms.ListManagerBindingsCollection.AddCore(Binding dataBinding)
   in System.Windows.Forms.BindingsCollection.Add(Binding binding)
   in System.Windows.Forms.BindingContext.UpdateBinding(BindingContext newBindingContext, Binding binding)
   in System.Windows.Forms.Control.UpdateBindings()
   in System.Windows.Forms.Control.OnBindingContextChanged(EventArgs e)
   in System.Windows.Forms.Control.OnParentBindingContextChanged(EventArgs e)
   in System.Windows.Forms.Control.OnBindingContextChanged(EventArgs e)
   in System.Windows.Forms.Control.OnParentBindingContextChanged(EventArgs e)
   in System.Windows.Forms.Control.OnBindingContextChanged(EventArgs e)
   in System.Windows.Forms.Control.OnParentBindingContextChanged(EventArgs e)
   in System.Windows.Forms.Control.OnBindingContextChanged(EventArgs e)
   in System.Windows.Forms.Control.OnParentBindingContextChanged(EventArgs e)
   in System.Windows.Forms.Control.OnBindingContextChanged(EventArgs e)
   in System.Windows.Forms.Control.OnParentBindingContextChanged(EventArgs e)
   in System.Windows.Forms.Control.OnBindingContextChanged(EventArgs e)
   in System.Windows.Forms.Control.set_BindingContextInternal(BindingContext value)
   in System.Windows.Forms.ContainerControl.set_BindingContext(BindingContext value)
   in System.Windows.Forms.ContainerControl.get_BindingContext()
   in System.Windows.Forms.Control.get_BindingContextInternal()
   in System.Windows.Forms.ContainerControl.get_BindingContext()
   in System.Windows.Forms.Control.get_BindingContextInternal()
   in System.Windows.Forms.ContainerControl.get_BindingContext()
   in System.Windows.Forms.Control.get_BindingContextInternal()
   in System.Windows.Forms.ContainerControl.get_BindingContext()
   in System.Windows.Forms.Control.get_BindingContextInternal()
   in System.Windows.Forms.Control.get_BindingContext()
   in System.Windows.Forms.Control.get_BindingContextInternal()
   in System.Windows.Forms.Control.get_BindingContext()
   in System.Windows.Forms.Control.UpdateBindings()
   in System.Windows.Forms.Control.OnBindingContextChanged(EventArgs e)
   in System.Windows.Forms.DataGridView.OnBindingContextChanged(EventArgs e)
   in System.Windows.Forms.Control.OnParentBindingContextChanged(EventArgs e)
   in System.Windows.Forms.Control.OnBindingContextChanged(EventArgs e)
   in System.Windows.Forms.Control.OnParentBindingContextChanged(EventArgs e)
   in System.Windows.Forms.Control.OnBindingContextChanged(EventArgs e)
   in System.Windows.Forms.ContainerControl.OnCreateControl()
   in System.Windows.Forms.UserControl.OnCreateControl()
   in System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   in System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   in System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   in System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   in System.Windows.Forms.Control.CreateControl()
   in System.Windows.Forms.Control.WmShowWindow(Message& m)
   in System.Windows.Forms.Control.WndProc(Message& m)
   in System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   in System.Windows.Forms.ContainerControl.WndProc(Message& m)
   in System.Windows.Forms.Form.WmShowWindow(Message& m)
   in System.Windows.Forms.Form.WndProc(Message& m)
...
   in System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   in System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   in System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
4

2 に答える 2

2

間接レイヤーを提供するには、 BindingSourceが必要です。

bindingSource1 = new BindingSource(components);
bindingSource1.DataMember = "Details";
bindingSource1.DataSource = typeof(MasterViewModel);

Binding binding = new Binding("Text", bindingSource1, "SubProperty");
binding.FormattingEnabled = true;
binding.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
binding.ControlUpdateMode = ControlUpdateMode.OnPropertyChanged;

textBox.DataBindings.Add(binding);

より詳細な例: C# 2.0 の BindingSource と BindingNavigator

于 2011-07-18T22:15:52.150 に答える
0

代わりに、次のように試してみてください。

 Binding binding = 
    new Binding("Text", masterViewModel.SelectedDetail, "SubProperty");
于 2011-07-07T11:41:29.733 に答える