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

时间:2009-06-26 12:22:44

标签: wpf data-binding combobox textblock valueconverter

我有一个简单的Item类,看起来像这样:

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对象列表(List< Item>)并创建一个使用此XAML代码绑定到此DependencyProperty的ComboBox:

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

如果我执行下面的代码一次,数据绑定工作正常,如果我再次执行它,转换失败的方式如何:

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方法现在传递了一个字符串对象作为第一个参数而不是一个Item-object?

我做错了什么?

此致 肯尼斯

3 个答案:

答案 0 :(得分:0)

替代方法,

  1. 您可以从Object而不是DependencyObject
  2. 派生您的类
  3. 您可以实现INotifyPropertyChange接口
  4. 当No或Name中的任何一个更改时,您可以实现只读属性和触发通知事件。
  5. public class Item: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;
        }
    }
    

    }

    现在您只能绑定“DisplayName”属性而不是转换器..

    1. 实现转换器非常复杂
    2. 基于DependencyObject的类只应用于UI目的

答案 1 :(得分:0)

简单的解决方法是检查传递给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();
    }

答案 2 :(得分:-1)

如果要使用数据绑定,则应将集合分配给ItemsSource,而不是Items。我认为这可能会解决这个问题。