我与价值转换器数据绑定不起作用

问题描述:

我有一个简单的项目级的,看起来像这样:我与价值转换器数据绑定不起作用

public class Item : DependencyObject 
{ 
    public int No 
    { 
     get { return (int)GetValue(NoProperty); } 
     set { SetValue(NoProperty, value); } 
    } 

    public string Name 
    { 
     get { return (string)GetValue(NameProperty); } 
     set { SetValue(NameProperty, value); } 
    } 

    public static readonly DependencyProperty NoProperty = DependencyProperty.Register("No", typeof(int), typeof(Item)); 
    public static readonly DependencyProperty NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Item)); 
} 

而且一个ValueConverter,看起来像这样:

[ValueConversion(typeof(Item), typeof(string))] 
internal class ItemToStringConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value == null) 
     { 
      return null; 
     } 

     var item = ((Item)value); 

     var sb = new StringBuilder(); 
     sb.AppendFormat("Item # {0}", item.No); 

     if (string.IsNullOrEmpty(item.Name) == false) 
     { 
      sb.AppendFormat(" - [{0}]", item.Name); 
     } 

     return sb.ToString(); 
    } 


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

在我的WPF窗口中,我声明了一个DependencyProperty(称为Items),它包含Item对象列表(列表< Item>),并使用此XAML代码创建一个绑定到此DependencyProperty的ComboBox:

<ComboBox ItemsSource="{Binding ElementName=mainWindow, Path=Items}"> 
    <ComboBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Converter={StaticResource itemToStringConverter}}"/> 
     </DataTemplate> 
    </ComboBox.ItemTemplate> 
</ComboBox> 

如果我执行下面的代码一次,绑定工作正常,howevery如果我再次执行它的价值皈依失败:

var item1 = new Item {Name = "Item A", No = 1}; 
var item2 = new Item {Name = "Item B", No = 2}; 
var item3 = new Item {Name = "Item C", No = 3}; 
Items = new List<Item> {item1, item2, item3}; 

的问题是,该ItemToStringConverter.Convert方法现在通过一个字符串-object作为第一个参数而不是Item对象?

我在做什么错?

问候, 肯尼斯

简单的解决方法是检查传递给您的ValueConverter的类型。更改转换方法如下:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { 
     var item = value as Item; 
     if(item == null) { return null; } 
     var sb = new StringBuilder(); 
     sb.AppendFormat("Item # {0}", item.No); 
     if(string.IsNullOrEmpty(item.Name) == false) { 
      sb.AppendFormat(" - [{0}]", item.Name); 
     } 
     return sb.ToString(); 
    } 

如果你想使用数据绑定,您应该分配您的收藏中的ItemsSource,而不是项目。我认为这可能会解决这个问题。

+0

我想我已经做到了,没有我? ComboBox的ItemsSource属性绑定项目属性... 如果我错了,请纠正我。 – kennethkryger 2009-06-26 12:49:44

+0

D'oh!错过了 - 我认为这是您分配给ListBox的Items,而不是您的对象。我的错。 – 2009-06-26 15:20:17

替代做法,

  1. 可以派生自对象,而不是DependencyObject的
  2. 类可以实现INotifyPropertyChange接口
  3. 你可以实现一个只读属性和火灾通知事件时,任何否或名称更改。

公共类项目:System.ComponentModel.INotifyPropertyChanged {

public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; 


private void Notify(string p) 
{ 
    if (PropertyChanged != null) 
     PropertyChanged(this, 
      new System.ComponentModel.PropertyChangedEventArgs(p)); 
} 

private int _No = 0; 
public int No 
{ 
    get 
    { 
     return _No; 
    } 
    set 
    { 
     _No = value; 
     Notify("No"); 
     Notify("DisplayName"); 
    } 
} 


private string _Name = ""; 
public string Name 
{ 
    get 
    { 
     return _Name; 
    } 
    set 
    { 
     _Name = value; 
     Notify("Name"); 
     Notify("DisplayName"); 
    } 
} 

public string DisplayName 
{ 
    get 
    { 
     string sb = string.Format("Item # {0}", _No); 
     if (!string.IsNullOrEmpty(_Name)) 
      sb += _Name; 
     return sb; 
    } 
} 

}

现在你只能绑定 “显示名称” 属性,而不是转换器..

  1. 转换器实施相当复杂
  2. And Depe基于nObjectObject的类只能用于UI目的
+0

我的示例从我的原始代码简化了很多,而Item实际上是从BusinessBase派生的(我使用的是CSLA.NET)。 但是,添加DisplayName属性是一个好主意。 但我仍然无法弄清楚,为什么我的转换器是用字符串值调用的? – kennethkryger 2009-06-26 12:48:21