我正在尝试在Windows窗体项目中使用master/detail模式实现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);
它完美无缺(如WPF !!!)......直到SelectedDetail为null(对于我的逻辑,SelectedDetail null表示在主视图中没有选择任何内容)。如果SelectedDetail为null,我得到一个ArgumentNullException(参数名称:component)。
有没有办法处理“父”属性的可空性(在导航路径中)?
这是异常堆栈跟踪:
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)
答案 0 :(得分: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);
答案 1 :(得分:0)
您可能希望尝试这样做:
Binding binding =
new Binding("Text", masterViewModel.SelectedDetail, "SubProperty");