WPF說數據項不為空時為空 (WPF says that data item is null when it is not null)


問題描述

WPF說數據項不為空時為空 (WPF says that data item is null when it is not null)

I have a ViewModel class that I use with WPF and MVVM:

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

The _Backplanes collection is created and populated in the constructor and never changes.

I have a control that uses an instance of this ViewModel as its DataContext. The user can choose the CurrentBackplane with a ComboBox:

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

The CurrentBackplane may also be changed in code.

I put a break point on the get of CurrentBackplane. The cb variable is not null. But, immediately after WPF requests its value, I get the following in the Output window:

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')

Why is WPF telling me the data item is null?

I'm not sure what I'm doing wrong. The program actually runs fine, but I'm trying to track down a memory leak that I think may be related to this issue.


參考解法

方法 1:

Have you tried setting _CurrentBackplane after you set the collection's value in the constructor to immediately be the first value and change the getter code to just return _CurrentBackplane?

_CurrentBackplane = Backplanes.First();  

and 

public BackplaneViewModel CurrentBackplane {  
    get {   
        return _CurrentBackplane;  
    }  
    set { _CurrentBackplane = value; }  
}  

方法 2:

in addition to Joshs answer you should raise propertychanged in your setter

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

and you should set the Mode to TwoWay for your SelectedItem

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

and btw you just get a binding information not a binding error

方法 3:

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.

方法 4:

I 'm not sure if this is the answer, but give it a try. In your application set:

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

This might solve the problem.

方法 5:

To me the solution was to recheck it after DataContext property has been reset, then resetting the binding:

<pre class="lang-cs prettyprint-override">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);
</code></pre>

(by kenJoshblindmeisBijingtonuser3083911Shimmy Weitzhandler)

參考文件

  1. WPF says that data item is null when it is not null (CC BY-SA 3.0/4.0)

#mvvm #wpf #data-binding #.net #xaml






相關問題

WPF View 在關閉時將 ViewModel 屬性設置為 null (WPF View sets ViewModel properties to null on closing)

在文本框中正確輸入後啟用按鈕 (Button Enable After Correct Input In TextBox)

WPF說數據項不為空時為空 (WPF says that data item is null when it is not null)

MVVM - 如何將 ViewModel 包裝在 ViewModel 中? (MVVM - How to wrap ViewModel in a ViewModel?)

關於服務參考和 MVVM 模式的幾個一般問題 (A few general questions about Service Reference and MVVM pattern)

WPF MVVM 鏈接視圖 (WPF MVVM Linked Views)

wpf 樹視圖 mvvm (wpf treeview mvvm)

如何在 MVVM Light 的 ListView 中的 ComboBox 中顯示列表? (How to show a List in a ComboBox in a ListView in MVVM Light?)

多次調用 PropertyChanged 的 ViewModel 屬性 (ViewModel properties with multiple calls to PropertyChanged)

如何將圖像存儲在類庫中並從任何類訪問它 (How can i store an image in a class library and access it from any class)

Silverlight MVVM 隔離存儲 (Silverlight MVVM Isolated Storage)

如何將文本框的borderBrush屬性綁定到viewmodel中的屬性,類型轉換錯誤 (How to bind the borderBrush property of a textbox to a property in viewmodel, type conversion error)







留言討論