2013-12-12 42 views
1

我最近發現了索引屬性。這看起來像是完美的解決方案,在這種情況下,我所使用的數據最好在集合中表達,但仍需要作爲可用於XAML數據綁定的屬性來實現。我只是開始創建索引屬性的測試,並且我在那裏沒有問題,但我似乎無法使綁定工作。C#WPF綁定到索引屬性 - 我做錯了什麼?

任何人都可以指出我要去哪裏錯了嗎?

下面是測試類與嵌套類創建索引屬性:

public class TestListProperty 
{ 

    public readonly ListProperty ListData; 

    //--------------------------- 
    public class ListProperty : INotifyPropertyChanged 
    { 
     private List<string> m_data; 

     internal ListProperty() 
     { 
      m_data = new List<string>(); 
     } 

     public string this[int index] 
     { 
      get 
      { 
       if (m_data.Count > index) 
       { 
        return m_data[index]; 
       } 
       else 
       { 
        return "Element not set for " + index.ToString(); 
       } 
      } 
      set 
      { 
       if (m_data.Count > index) 
       { 
        m_data[index] = value; 
       } 
       else 
       { 
        m_data.Insert(index, value); 
       } 
       OnPropertyChanged("Item[]"); 
       Console.WriteLine(value); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected virtual void OnPropertyChanged(string propertyName) 
     { 
      PropertyChangedEventHandler handler = PropertyChanged; 
      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 

    } 
    //--------------------------- 
    public TestListProperty() 
    { 
     ListData = new ListProperty(); 
    } 

} 

這裏是XAML:

<Window x:Class="TestIndexedProperties.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 

     <Grid.RowDefinitions> 
      <RowDefinition/> 
      <RowDefinition/> 
      <RowDefinition/> 
     </Grid.RowDefinitions> 

     <TextBox Width="200" Grid.Row="0" Text="{Binding Path=ListData[0], Mode=TwoWay}" /> 
     <TextBox Width="200" Grid.Row="1" Text="{Binding Path=ListData[1], Mode=TwoWay}" /> 
     <TextBox Width="200" Grid.Row="2" Text="{Binding Path=ListData[2], Mode=TwoWay}" /> 


    </Grid> 
</Window> 

這裏是窗口代碼:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     TestListProperty test = new TestListProperty(); 

     this.DataContext = test; 

     test.ListData[0] = "ABC"; 
     test.ListData[1] = "Pleeez 2 wurk?"; 
     test.ListData[2] = "Oh well"; 

    } 
} 

感謝您的幫助!

+0

運行時在輸出窗口中發生任何綁定錯誤/警告? –

回答

0

代碼中沒有任何機制可以在列表發生更改時向前端表明,即ListProperty正在實現INotifyPropertyChanged而不是INotifyCollectionChanged。最簡單的解決將是改變M_DATA鍵入的ObservableCollection和綁定你的XAML控制到相反,雖然這可能違背了你想在第一時間做的目的。 「正確」的方法是訂閱CollectionChanged事件並傳播消息:

public class TestListProperty 
{ 
    public ListProperty ListData { get; private set; } 

    //--------------------------- 
    public class ListProperty : INotifyCollectionChanged 
    { 
     private ObservableCollection<string> m_data; 

     internal ListProperty() 
     { 
      m_data = new ObservableCollection<string>(); 
      m_data.CollectionChanged += (s, e) => 
      { 
       if (CollectionChanged != null) 
        CollectionChanged(s, e); 
      }; 
     } 

     public string this[int index] 
     { 
      get 
      { 
       if (m_data.Count > index) 
       { 
        return m_data[index]; 
       } 
       else 
       { 
        return "Element not set for " + index.ToString(); 
       } 
      } 
      set 
      { 
       if (m_data.Count > index) 
       { 
        m_data[index] = value; 
       } 
       else 
       { 
        m_data.Insert(index, value); 
       } 
       Console.WriteLine(value); 
      } 
     } 

     public event NotifyCollectionChangedEventHandler CollectionChanged; 

    } 
    //--------------------------- 
    public TestListProperty() 
    { 
     ListData = new ListProperty(); 
    } 
} 
+0

我現在已經啓動了代碼。許多單位感謝您的幫助! –

+0

你如何傳播信息?我看不到任何通知 –

+0

通過引發CollectionChanged事件發生更改通知。 m_data集合生成自己的CollectionChanged事件,所以父包裝需要訂閱這些事件併爲其自身引發事件。在這種情況下,不需要INotifyPropertyChanged,因爲m_data具有私有setter,因此永遠不能更改。 –