2014-04-26 77 views
0

所以我想打造出一個項目,將允許用戶在表格的左側鍵入一些文本到文本框,並會從我的數據源過濾掉可用項目名單。哲學對WPF綁定到參數

<Label Content="Enter item name below"></Label> 
<TextBox Name="SearchTermTextBox" TabIndex="0" Text="" /> 

我的印象是我可以綁定到數據源的列表,然後使用轉換器過濾出不同於字符串的項目。

<ListBox DataContext="{Binding Colors}"> 
    <ListBox.ItemsSource> 
    <MultiBinding Converter="{StaticResource FilterTextValueConverter}" ConverterParameter="{Binding ElementName=SearchTermTextBox, Path=Text}" /> 
    </ListBox.ItemsSource> 
    <ListBox.ItemTemplate> 
     //etc... 
    </ListBox.ItemTemplate> 
</ListBox> 

但是,除非使用稱爲依賴項屬性的東西,否則無法綁定到converterparameter中的elementname。

編輯:看,我已經創建了上面的代碼混淆,這裏就是我想要綁定的轉換器:

public class FilterTextValueConverter : IValueConverter 
{ 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     var trackedColors = value as List<Colors>; 
     if (trackedColors != null) 
      return (trackedColors).Where(item => item.ColorName.Contains(parameter.ToString())).ToList(); 

     return null; 
    } 

    public object ConvertBack(object value, Type targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 


public class Colors 
{ 
    public String ColorName; 
    public String Description; 
} 

什麼是錯在這裏我的做法?顯然,我很憤怒WPF神,因爲這是一個相當直接的操作,但我原則上被拒絕。任何幫助,將不勝感激。

回答

2

簡單與轉換器結合將在這裏工作,沒有必要MultiBinding。

<ListBox ItemsSource="{Binding Path=Text, ElementName=SearchTermTextBox, 
          Converter="{StaticResource FilterTextValueConverter}"> 
    ...... 
</ListBox> 

假設FilterTextValueConverter正在實施IValueConverter,你可以從傳遞到轉換方法價值訪問文本。

public class FilterTextValueConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, 
          System.Globalization.CultureInfo culture) 
    { 
     string text = value.ToString(); // TEXT for textBox can be accessed here. 
     return new List<string>(); // Return filtered list from here. 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, 
           System.Globalization.CultureInfo culture) 
    { 
     return Binding.DoNothing; 
    } 
} 

UPDATE

如果你想傳遞多個綁定的轉換器,使用IMultiValueConverter因爲ConverterParameter不依賴屬性,因此不能約束。

XAML

<ListBox DataContext="{Binding Colors}"> 
    <ListBox.ItemsSource> 
     <MultiBinding Converter="{StaticResource FilterTextValueConverter}"> 
      <Binding/> 
      <Binding ElementName="SearchTermTextBox" Path="Text"/> 
     </MultiBinding> 
    </ListBox.ItemsSource> 
</ListBox> 

轉換

public class FilterTextValueConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, 
          System.Globalization.CultureInfo culture) 
    { 
     var trackedColors = values[0] as List<Colors>; 
     if (trackedColors != null && !String.IsNullOrEmpty(values[1].ToString())) 
      return (trackedColors).Where(item => 
        item.ColorName.Contains(values[1].ToString())).ToList(); 

     return null; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, 
           object parameter, 
           System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

不幸的是,我需要將ConverterParameter綁定到SearchTermTextBox,而Visual Studio不允許這樣做。我的轉換器必須返回列表。 –

+0

我編輯了原文,以更好地解釋我的情況。我同意這個多重是不必要的,它只是一個讓它接受的實驗。 –

+0

轉換器參數不能綁定。你需要使用'IMultiValueConverter'。我已經更新了答案。看看是否有幫助。 –

0

我繼續尋找到這個問題,接受的答案被張貼後良好,爲我工作。我發現,把你試圖獲得一個新的依賴屬性的控件封裝起來以允許正確的綁定是一件相當簡單的任務。

我不會接受我自己的答案,這決定了這麼多之後,但這似乎(在我的業餘觀點)像一個更好的解決方案比儘管是一個有點複雜加入轉爐:

注這是爲了對文本框的caretindex屬性進行新的依賴關係,而不是綁定的原始問題,但它只是需要一些智能重命名才能使其工作;)。

public class TextBoxDependencyWrapper : TextBox 
    { 
     public static readonly DependencyProperty CaretIndexProperty = DependencyProperty.Register(
      "CaretIndex", typeof (int), typeof (TextBoxDependencyWrapper), new FrameworkPropertyMetadata(default(int), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, CaretIndexChanged)); 

     protected override void OnKeyUp(KeyEventArgs e) //Event that changes the property we're trying to track 
     { 
      base.OnKeyUp(e); 
      CaretIndex = base.CaretIndex; 
     } 

     protected override void OnKeyDown(KeyEventArgs e) //Event that changes the property we're trying to track 
     { 
      base.OnKeyDown(e); 
      CaretIndex = base.CaretIndex; 
     } 

     public new int CaretIndex 
     { 
      get { return (int) GetValue(CaretIndexProperty); } 
      set { SetValue(CaretIndexProperty, value); } 
     } 
    }