1

我有一个用于 WPF 和 MVVM 的 ViewModel 类:

public class ViewModel {

    /* Other members here... */

    public ReadOnlyObservableCollection<BackplaneViewModel> Backplanes {
        get { return _Backplanes; }
    }

    public BackplaneViewModel CurrentBackplane {
        get { 
            var cb = _CurrentBackplane ?? (_CurrentBackplane = Backplanes.First()); 
            return cb;
        }
        set { 
            if (_CurrentBackplane == value) return;
            _CurrentBackplane = value; 
            RaisePropertyChanged("CurrentBackplane");
        }
    }
}

集合在_Backplanes构造函数中创建和填充,并且永远不会更改。

我有一个控件,它使用 this 的一个实例ViewModel作为它的DataContext. 用户可以选择CurrentBackplane带有 a 的ComboBox

<ComboBox ItemsSource="{Binding Backplanes}"
          SelectedItem="{Binding CurrentBackplane}"
          DisplayMemberPath="BackplaneIndex" />

CurrentBackplane也可以在代码中更改。

get我在of上放了一个断点CurrentBackplanecb变量不是null。但是,在WPF请求它的值之后,我立即在输出窗口中得到以下信息:

System.Windows.Data Information: 40 : BindingExpression path error: 'BackplaneIndex' property not found for 'object' because data item is null.  This could happen because the data provider has not produced any data yet. BindingExpression:Path=BackplaneIndex; DataItem=null; target element is 'ComboBox' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 19 : BindingExpression cannot retrieve value due to missing information. BindingExpression:Path=BackplaneIndex; DataItem=null; target element is 'ComboBox' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 20 : BindingExpression cannot retrieve value from null data item. This could happen when binding is detached or when binding to a Nullable type that has no value. BindingExpression:Path=BackplaneIndex; DataItem=null; target element is 'ComboBox' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=BackplaneIndex; DataItem=null; target element is 'ComboBox' (Name=''); target property is 'NoTarget' (type 'Object')

为什么WPF告诉我数据项为空?

我不确定我做错了什么。该程序实际上运行良好,但我正在尝试追踪我认为可能与此问题有关的内存泄漏。

4

5 回答 5

0

我不确定这是否是答案,但请尝试一下。在您的应用程序集中:

System.Diagnostics.PresentationTraceSources.DataBindingSource.Switch.Level = System.Diagnostics.SourceLevels.Critical;

这可能会解决问题。

于 2013-12-12T05:03:13.757 回答
0

在将构造函数中的集合值设置为立即成为第一个值并将 getter 代码更改为仅返回 _CurrentBackplane 后,您是否尝试过设置 _CurrentBackplane?

_CurrentBackplane = Backplanes.First();  

public BackplaneViewModel CurrentBackplane {  
    get {   
        return _CurrentBackplane;  
    }  
    set { _CurrentBackplane = value; }  
}  
于 2012-07-31T20:29:07.703 回答
0

Can you check if the DataContext has actually been set to your ViewModel instance before the logging is written to the output window? You can do this by hooking up an event handler to the DataContextChanged event.

I am seeing a similar problem with my code, unfortunately I haven't worked out how to prevent it but I shall keep you posted if I do.

于 2013-03-01T11:35:17.193 回答
0

除了 Joshs 的回答,你应该在你的 setter 中提出 propertychanged

set { _CurrentBackplane = value; OnPropertyChanged("CurrentBackplane "); }

你应该为你的 SelectedItem 设置 Mode 为 TwoWay

SelectedItem="{Binding CurrentBackplane, Mode=TwoWay}"

顺便说一句,您只会得到绑定信息而不是绑定错误

于 2012-08-01T06:47:20.733 回答
0

对我来说,解决方案是在重置属性后重新检查它DataContext,然后重置绑定:

var resolvedSource = bindingExpression.ResolvedSource;
if (resolvedSource == null)
{
  textBox.DataContextChanged += dataContextChanged;

  static void dataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
  {
    var frameworkElement = (FrameworkElement)sender;
    var be = frameworkElement.GetBindingExpression(TextBox.TextProperty);
    var newBe = BindingOperations.SetBinding(
      (DependencyObject)sender, TextBox.TextProperty, be.ParentBinding);
    Debug.Assert(newBe is BindingExpression);
    Debug.Assert(newBe.DataItem != null);

    //here newBe.DataItem should not be null
    addValidationRules((BindingExpression)newBe);
    frameworkElement.DataContextChanged -= dataContextChanged;
  }
  return;
}
addValidationRules(bindingExpression);
于 2019-12-22T00:53:12.697 回答