2011-03-24 90 views
11

我試圖將一個TextBlock綁定到ObservableCollection中的特定元素。 這就是我現在做:綁定到數組元素

private ObservableCollection<double> arr = new ObservableCollection<double>(); 
public ObservableCollection<double> Arr { get { return arr; } set { arr = value; } } 

testBox.DataContext = this; 

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    Arr[0] += 1.0; 
} 

    [ValueConversion(typeof(ObservableCollection<double>), typeof(String))] 
    public class myObsCollConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      ObservableCollection<double> l = value as ObservableCollection<double>; 
      if(l == null) 
       return DependencyProperty.UnsetValue; 
      int i = int.Parse(parameter.ToString()); 

      return l[i].ToString(); 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      return DependencyProperty.UnsetValue; 
     } 
    } 


    <Window.Resources> 
     <local:myObsCollConverter x:Key="myConverter"/> 
    </Window.Resources> 

     <TextBlock Name="testBox" Text="{Binding Path=Arr,Converter={StaticResource myConverter}, ConverterParameter=0}" /> 

我看到的是,TESTBOX顯示編曲的第一個值在創建時。 但它並不反映對此元素的任何更改。 爲了在我的文本框中看到對Arr [0]的更改,我需要做些什麼?

回答

21

不需要轉換器。您可以直接綁定到Arr[0]這樣

<TextBlock Name="testBox" Text="{Binding Path=Arr[0]}"/> 

Arr元素需要實現INotifyPropertyChanged雖然以動態地更新。

更新:更詳細地說明一點:

public class MyDouble : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private double _Value; 
    public double Value 
    { 
     get { return _Value; } 
     set { _Value = value; OnPropertyChanged("Value"); } 
    } 

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

然後

ObservableCollection<MyDouble> Arr { get; set; } 

並綁定到

<TextBlock Name="testBox" Text="{Binding Path=Arr[0].Value}"/> 
+1

但它不應該工作嗎?當值被替換時,ObservableCollection會引發一個CollectionChanged事件......我很驚訝綁定沒有注意到這一點。 – 2011-03-24 07:52:22

+0

那麼,你綁定到元素,而不是集合,所以我猜UI只會監聽PropertyChanged事件 – ChrisWue 2011-03-24 07:58:55

+0

如果我不想將元素索引(0)綁定到另一個控件,該怎麼辦? 例如我有一個ComboBox來選擇我的testBox應該顯示的元素的索引。 – MTR 2011-03-24 13:01:57

3

ObservableCollection s不會傳播對存儲在屬於集合的對象內的值的更改。它只會在收集本身的內容發生變化(即添加,刪除,重新排序項目)時觸發通知。如果您希望在集合中的值發生更改時更新UI,那麼您必須單獨將它們連接起來。

+0

這是*取代*項目,雖然沒有修改對象的內部數據。我剛剛檢查過,在這種情況下它將*觸發CollectionChanged事件(使用Replace操作)。 – 2011-03-24 07:32:20

0

,你可以用這種方式在我的情況下,我想綁定布爾數組的可見性: 後面的代碼:

using System.Windows; 
public static readonly DependencyProperty ButtonVisibleProperty = 
     DependencyProperty.Register("ButtonVisible", typeof(BindingList<Boolean>), typeof(BaseWindow), new PropertyMetadata(new BindingList<Boolean>())); 
public BindingList<Boolean> ButtonVisible 
    { 
     get { return (BindingList<Boolean>)GetValue(BaseWindow.ButtonVisibleProperty); } 
     set 
     { 
      SetValue(BaseWindow.ButtonVisibleProperty, value); 
      OnPropertyChanged("ButtonVisible"); 
     } 
    } 

,並在XAML:

Visibility=""{Binding Path=ButtonVisible[0], RelativeSource={RelativeSource AncestorType={x:Type Window}}}" 

當心!在我的情況祖先類型取決於你的祖先是一個窗口