2

我試圖用多級屬性路徑將依賴項屬性綁定到INotifyPropertyChanged -enabled屬性。綁定無效嵌套屬性

當財產的所有人對象不是null,結合作品,但如果車主對象null,綁定不會做任何事情(轉換器不叫,不使用TargetNullValue)。

下面是一些最小的樣品代碼來重現問題:


Window1.xaml.cs:

using System; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.ComponentModel; 

namespace NPCPropertyPath 
{ 
    public abstract class VMBase : INotifyPropertyChanged 
    { 
     protected void OnPropertyChanged(string propertyName) 
     { 
      OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); 
     } 

     protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) 
     { 
      if (e == null) { 
       throw new ArgumentNullException("e"); 
      } 

      if (PropertyChanged != null) { 
       PropertyChanged(this, e); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
    } 

    public partial class Window1 : Window 
    { 
     private class MyConverter : IValueConverter 
     { 
      public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
      { 
       if (value == null) { 
        return null; 
       } else if (value is int) { 
        return (((int)value) + 15).ToString(); 
       } else { 
        return "no int"; 
       } 
      } 

      object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
      { 
       throw new NotSupportedException(); 
      } 
     } 

     private class InnerVM : VMBase 
     { 
      private int myValue; 

      public int MyValue { 
       get { 
        return myValue; 
       } 
       set { 
        if (myValue != value) { 
         myValue = value; 
         OnPropertyChanged("MyValue"); 
        } 
       } 
      } 
     } 

     private class OuterVM : VMBase 
     { 
      private InnerVM thing; 

      public InnerVM Thing { 
       get { 
        return thing; 
       } 
       set { 
        if (thing != value) { 
         thing = value; 
         OnPropertyChanged("Thing"); 
        } 
       } 
      } 
     } 

     private readonly OuterVM vm = new OuterVM(); 

     public Window1() 
     { 
      InitializeComponent(); 

      var txt = new TextBlock(); 
      txt.SetBinding(TextBlock.TextProperty, 
          new Binding("Thing.MyValue") { 
          Source = vm, 
          Mode = BindingMode.OneWay, 
          Converter = new MyConverter(), 
          TargetNullValue = "(error)" 
          }); 
      container.Content = txt; 

      var txt2 = new TextBlock(); 
      txt2.SetBinding(TextBlock.TextProperty, 
          new Binding("Thing") { 
           Source = vm, 
           Mode = BindingMode.OneWay, 
           Converter = new MyConverter(), 
           TargetNullValue = "(error)" 
          }); 
      container2.Content = txt2; 
     } 

     void Button_Click(object sender, RoutedEventArgs e) 
     { 
      vm.Thing = new InnerVM(); 
      vm.Thing.MyValue += 10; 
     } 
    } 
} 

Window1.xaml:

<Window x:Class="NPCPropertyPath.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="NPCPropertyPath" Height="300" Width="300"> 
    <StackPanel> 
     <Button Content="Change value" Click="Button_Click"/> 
     <ContentControl Name="container"/> 
     <ContentControl Name="container2"/> 
    </StackPanel> 
</Window> 

當然,這是我真正的應用程序的顯著簡化形式,其中有相當多的事情和所涉及的類不是在兩個文件中擠在一起(甚至在同一程序),其中他們都可以看到對方。

此示例顯示帶有按鈕和兩個內容控件的窗口。每個內容控件都包含一個TextBlock,其Text property已綁定到來自視圖模型的屬性。視圖模型實例(類型爲OuterVM)被分配給每個綁定的Source property

OuterVM implements INotifyPropertyChanged;它有一個屬性Thing類型InnerVM(也執行INotifyPropertyChanged),其中又有一個屬性MyValue

第一個文本塊綁定到Thing.MyValue,第二個僅僅到Thing。如果目標屬性爲null,則這兩個綁定都有一個轉換器集合以及應該顯示在文本塊上的TargetNullValue屬性的值。

ThingOuterVM實例的屬性最初是null。點擊按鈕時,會爲該屬性分配一些內容。

問題:只有第二個文本塊最初顯示任何內容。綁定到Thing.MyValue的那個都不會調用轉換器(如通過設置斷點所證明的),也不會使用TargetNullValue屬性的值。

爲什麼?我怎樣才能讓第一個文本塊顯示默認值而不是Thing.MyValueThing未分配?

回答

2

爲此目的,您不應該使用TargetNullValue,您應該使用FallbackValue屬性Binding

+0

迷人的發現!在找到'TargetNullValue'屬性後,誰會考慮在文檔中查找額外的'FallbackValue'屬性? :) –